如何让.NET Core 6 Web API的[Authorize]特性正常工作
问题背景
作为.NET开发初学者,在.NET Core 6 Web API项目中以最简方式实现JWT认证时功能异常,需求为:调用GetProductList接口必须处于登录状态,测试环境为项目自带的Swagger。
现有代码
登录相关控制器(运行符合预期)
[HttpPost("login")] public async Task<ActionResult> Login(LoginDto request) { var user = GetUserFromRequest(request); if (user == null) return BadRequest("Invalid credentials."); string jwt = CreateJwtToken(user.Id.ToString()); Response.Cookies.Append(COOKIE_JWT, jwt, _cookieOptions); return Ok(); } [HttpGet("user")] public IActionResult GetUser() { try { var jwt = Request.Cookies[COOKIE_JWT]; var userId = VerifyJwtAndGetUserId(jwt); return Ok(GetUserById(userId)); } catch(Exception ex) { return Unauthorized(); } } public static string CreateJwtToken(string userId) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_KEY)); var cred = new SigningCredentials(key, SecurityAlgorithms.HmacSha256Signature); var token = new JwtSecurityToken( issuer: userId, expires: DateTime.Now.AddDays(365), signingCredentials: cred ); var jwt = new JwtSecurityTokenHandler().WriteToken(token); return jwt; } public static string VerifyJwtAndGetUserId(string jwt) { var tokenHandler = new JwtSecurityTokenHandler(); tokenHandler.ValidateToken(jwt, new TokenValidationParameters { IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_KEY)), ValidateIssuerSigningKey = true, ValidateIssuer = false, ValidateAudience = false }, out SecurityToken validatedToken); string userId = validatedToken.Issuer; return userId; }
待鉴权接口代码
[HttpGet("list")] //[Authorize] public async Task<ActionResult<List<Product>>> GetProductList() { return Ok(GetProducts()); }
异常表现
- 接口未添加
[Authorize]特性时可正常访问 - 添加
[Authorize]特性后接口返回401状态码,同项目下手动读取Cookie校验JWT的GetUser接口可正常访问 - 401响应头内容:
content-length: 0 date: Mon,13 Jun 2022 23:27:32 GMT server: Kestrel www-authenticate: Bearer
现有Program.cs JWT配置
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.RequireHttpsMetadata = false; options.TokenValidationParameters = new TokenValidationParameters { IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JWT_KEY)), ValidateIssuerSigningKey = true, ValidateIssuer = false, ValidateAudience = false }; options.Events = new JwtBearerEvents { OnMessageReceived = ctx => { ctx.Token = ctx.Request.Cookies["jwt"]; return Task.CompletedTask; } }; });
核心疑问
如何让[Authorize]特性正常生效?
解决方案
将app.UseAuthentication();移动到app.UseAuthorization();之前注册即可。
.NET Core中间件严格按照注册顺序执行,认证中间件必须先于授权中间件运行,才能在授权校验阶段前完成用户身份解析;若顺序颠倒,授权阶段无法获取有效用户身份,会直接返回401未授权响应。
内容的提问来源于stack exchange,提问作者Aximili
相关产品推荐
相关产品推荐

