ASP.NET Core中JWT角色授权返回401 Unauthorized问题求助
我正在使用ASP.NET Core开发基于JWT的认证与角色授权系统,用户登录时生成包含Role声明的JWT令牌,但请求带有[Authorize(Roles = "User")]特性的接口时,持续收到“401 Unauthorized”错误,请求协助排查。
相关代码
登录方法
public IDataResult<string> Login(UserForLoginDto userForLoginDto) { var userToCheck = _userService.GetByMail(userForLoginDto.Email).Data; if (userToCheck == null) { return new ErrorDataResult<string>("User not found"); } if (userToCheck.Password != userForLoginDto.Password) { return new DataResult<string>(null, false, "Invalid email or password"); } var userClaims = _userDal.GetClaims(userToCheck); var token = _tokenHelper.GenerateToken(userToCheck, userClaims); return new DataResult<string>(token, true, "Login successful"); }
令牌生成方法
public string GenerateToken(User user, List<OperationClaim> operationClaims) { var claims = new List<Claim> { new Claim(ClaimTypes.Name, user.Email) }; foreach (var operationClaim in operationClaims) { claims.Add(new Claim(ClaimTypes.Role, operationClaim.Name)); } var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["TokenOptions:SecurityKey"])); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); var token = new JwtSecurityToken( issuer: _configuration["TokenOptions:Issuer"], audience: _configuration["TokenOptions:Audience"], claims: claims, expires: DateTime.Now.AddDays(3), signingCredentials: creds); return new JwtSecurityTokenHandler().WriteToken(token); }
受保护接口
[HttpGet("GetAll")] [Authorize(Roles = "User")] public IActionResult GetAll() { var cars = _carService.GetAll(); if (cars.Success) return Ok(cars); return BadRequest(cars); }
认证配置
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = configuration["TokenOptions:Issuer"], ValidAudience = configuration["TokenOptions:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["TokenOptions:SecurityKey"])) }; }); app.UseAuthentication(); app.UseAuthorization();
请求截图

排查与解决建议
- 校验令牌内的Role声明:用JWT解码工具解析生成的令牌,确认
http://schemas.microsoft.com/ws/2008/06/identity/claims/role(ASP.NET Core对ClaimTypes.Role的默认映射)对应的声明值是否包含User。 - 确认中间件顺序:确保
app.UseAuthentication()在app.UseAuthorization()之前执行,且位于app.UseRouting()之后、app.UseEndpoints()之前。 - 核对TokenOptions配置:检查
appsettings.json中TokenOptions下的Issuer、Audience、SecurityKey是否与令牌生成逻辑中的配置完全一致,任何不匹配都会导致验证失败。 - 检查请求头格式:确认
Authorization头的格式为Bearer {token},无多余空格或拼写错误。 - 验证角色数据加载:在
Login方法中添加调试输出,确认_userDal.GetClaims(userToCheck)确实返回了包含User角色的列表。 - 启用验证日志:在JWTBearer配置中添加事件日志,查看验证失败的具体原因:
.AddJwtBearer(options => { // 原有配置... options.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { Console.WriteLine($"认证失败:{context.Exception.Message}"); return Task.CompletedTask; }, OnTokenValidated = context => { Console.WriteLine("令牌验证成功"); return Task.CompletedTask; } }; });
内容的提问来源于stack exchange,提问作者iremnur memiş
相关产品推荐
相关产品推荐

