.Net Framework 4.6.1 WebApi,属性路由和默认路由不起作用

问题描述

感谢您对此的任何帮助。我目前正在从事一个项目,我们基本上必须将旧的 .Net Framework MVC 应用程序转换为 React 前端使用的 API。我们基本上可以在不使用 ApiController 的情况下将 MVC 控制器转换为 API 控制器。现在我们意识到我们需要保护 API,并决定实施 JWT。

我能够实现 JWT 令牌创建,并且我在返回 JWT 的帐户控制器中工作。我遇到的问题是,我想在某些端点上实现授权,但在现有控制器上运行时遇到了问题。 https://github.com/DavidParks8/Owin-Authorization/wiki/Claims-Based-Authorization 上的文档说明我应该能够在任一类型的控制器上使用授权,所以我不知道我做错了什么。

我想可能是因为我使用的是 Controller 而不是 ApiController,所以我设置了一个测试控制器并根据我遵循的 JWT 教程创建了一些基本端点。问题是,当我尝试测试这些端点时,它们根本没有被击中,而且我收到了 404。

这是我的配置:

        {
            string secretKey = WebConfigurationManager.AppSettings["SecretKey"];
            SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretKey));

            // Configure the db context,user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(ApplicationDbContext.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);


            //Enable JWT Authentication:

            app.UseJwtBearerAuthentication(
                new JwtBearerAuthenticationoptions
                {
                    AuthenticationMode = AuthenticationMode.Active,TokenValidationParameters = new TokenValidationParameters()
                    {
                        ValidateIssuer = true,ValidateAudience = true,ValidateIssuerSigningKey = true,Validissuer = WebConfigurationManager.AppSettings["Audience"],ValidAudience = WebConfigurationManager.AppSettings["Audience"],IssuerSigningKey = _signingKey,ClockSkew = TimeSpan.Zero,ValidateLifetime = true,RequireExpirationTime = false
                    },});
            //Authorizationoptions options = new Authorizationoptions();
            app.UseAuthorization(options =>
            {
                options.AddPolicy("Principal",policy => policy.RequireClaim(Constants.JwtClaimIdentifiers.Rol,"Principal"));
                options.AddPolicy("Employee",Constants.JwtClaims.Employee));
                options.AddPolicy("Warranty",Constants.JwtClaims.Principal));
                options.AddPolicy("Admin",Constants.JwtClaims.Principal));
            });

这是基于我浏览过的文档和教程,并且正在使用 Microsoft.Owin.Security.Authorization 和 Microsoft.Owin.Security.Jwt

这是我的 WebApiConfig

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            // Configure Web API to use only bearer token authentication.
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
            var json = config.Formatters.JsonFormatter;
            json.SupportedMediaTypes
                .Add(new MediaTypeHeaderValue("text/html"));
            json.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
            // Web API routes
            config.MapHttpAttributeRoutes();

            config.EnableCors();

            //config.MessageHandlers.Add(new TokenValidationHandler());

            config.Routes.MapHttpRoute(
                name: "DefaultApi",routeTemplate: "api/{controller}/{action}/{id}",defaults: new { id = RouteParameter.Optional }
            );

            //var jsonpformatter = new JsonpMediaTypeFormatter(config.Formatters.JsonFormatter);
            //config.Formatters.Insert(0,jsonpformatter);
        }
    }

这是我的测试控制器:

public class TestController : ApiController
    {
        [HttpGet]
        [AllowAnonymous]
        [Route("GetToken")]
        public Object GetToken()
        {
            string key = "my_secret_key_12345"; //Secret key which will be used later during validation    
            var issuer = "example.com";  //normally this will be your site URL    

            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
            var credentials = new SigningCredentials(securityKey,SecurityAlgorithms.HmacSha256);

            //Create a List of Claims,Keep claims name short    
            var permClaims = new List<Claim>();
            permClaims.Add(new Claim(JwtRegisteredClaimNames.Jti,Guid.NewGuid().ToString()));
            permClaims.Add(new Claim("valid","1"));
            permClaims.Add(new Claim("userid","1"));
            permClaims.Add(new Claim("name","bilal"));

            //Create Security Token object by giving required parameters    
            var token = new JwtSecurityToken(issuer,//Issuer    
                issuer,//Audience    
                permClaims,expires: DateTime.Now.AddDays(1),signingCredentials: credentials);
            var jwtToken = new JwtSecurityTokenHandler().Writetoken(token);
            return new { data = jwtToken };
        }

        [HttpGet]
        [AllowAnonymous]
        [Route("GetName1")]
        public string GetName1()
        {
            if (User.Identity.IsAuthenticated)
            {
                var identity = User.Identity as ClaimsIdentity;
                if (identity != null)
                {
                    IEnumerable<Claim> claims = identity.Claims;
                }
                return "Valid";
            }
            else
            {
                return "Invalid";
            }
        }


        [HttpPost]
        [Route("GetName2")]
        public Object GetName2()
        {
            if (User.Identity is ClaimsIdentity identity)
            {
                IEnumerable<Claim> claims = identity.Claims;
                var name = claims.Where(p => p.Type == "name").FirstOrDefault()?.Value;
                return new
                {
                    data = name
                };

            }
            return null;
        }
    }

所以当我尝试调用 http://localhost:29523/api/Test/GetToken 时,我收到了 404 错误。我正在使用 Postman,我可以访问另一个控制器中的端点,但它是一个 MVC 控制器,它不遵循 API 路由。例如,/registration/GetAccountManagementInfo?userGuid=a182235e-c71d-47a5-b31d-f556288b3c3f 有效,我能够得到响应。

总而言之,我用这个 ApiController 进行测试的原因是因为如果我能做到这一点,并获得授权在 ApiController 上工作,那么我将把我的“注册”控制器转换成一个 ApiController,因为我无法让该控制器使用我设置的授权中间件。

无论如何,我确定我可以提供其他信息,但此时我无能为力,试图找出如何进一步解决此问题。

我知道它正在尝试到达控制器,因为如果我添加一个构造函数,它会在构造函数处遇到断点,但无法从那里找到路由。我不知道我的设置有什么问题,但我觉得这个设置必须有一些电线在某个地方交叉。这是我继承的一个应用程序。我希望我能用 .Net 核心开始一个新项目,但我们现在没有时间。

无论如何,抱歉这篇文章的长度,我真的希望有人能给我一些指导。到目前为止,我已经浏览了无数其他帖子,但我还没有找到任何可以帮助我解决这个问题的帖子。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)