ASP.NET Core Web API授权配置异常排查求助
问题:ASP.NET Core Web API JWT Bearer Token授权失败排查与优化建议
错误日志
[05:02:07 INF] Authorization failed. These requirements were not met:
RolesAuthorizationRequirement:User.IsInRole must be true for one of
the following roles: (Sudo)
[05:02:07 INF] AuthenticationScheme: Identity.Application was challenged.
[05:02:07 INF] Request finished HTTP/1.1 GET http://localhost:5259/api/auth/ - 302 0 null 6.7246ms
[05:02:07 INF] Request starting HTTP/1.1 GET http://localhost:5259/Account/Login?ReturnUrl=%2Fapi%2Fauth%2F - application/json null
问题背景
在ASP.NET Core Web API中结合JWT Bearer Token实现自定义授权策略,访问受保护路由时出现上述授权失败错误。已确认请求头正确携带Bearer Token,当前采用访问/刷新令牌模式,刷新令牌为HttpOnly Cookie(暂未测试)。
相关代码配置
Program.cs 配置
public static void ConfigureAuthentication(this IServiceCollection services, IConfiguration config) { services.AddAuthentication(options => { options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; }).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = config["JWT:Issuer"], ValidateAudience = false, ValidateLifetime = true, IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(config["JWT:Key"] ?? throw new Exception("Security Key not found within configuration"))) }; }); } public static void ConfigureAuthorization(this IServiceCollection services, IConfiguration config) { services.AddAuthorization(options => { options.AddPolicy("SudoPolicy", p => p.AddRequirements( new IsSudoRequirement() )); options.AddPolicy("SudoRole", p => p.RequireRole("Sudo")); }); } public static void ConfigureIdentity(this IServiceCollection services) { services.AddIdentity<Usuario, IdentityRole>(options => { options.Password.RequiredLength = 6; }).AddEntityFrameworkStores<AppDbContext>(); }
自定义授权策略
public class IsSudoHandler : AuthorizationHandler<IsSudoRequirement> { protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, IsSudoRequirement requirement) { if (context.User.HasClaim(c => c.Type == "Role" && c.Value.Contains("Sudo"))) { context.Succeed(requirement); } return Task.CompletedTask; } } public class IsSudoRequirement : IAuthorizationRequirement { public IsSudoRequirement() { IsSudo = true; } public bool IsSudo { get; } }
Access Token生成逻辑
public async Task<string> CreateAccessTokenAsync(Usuario usuario) { var roles = await _userManager.GetRolesAsync(usuario); var claims = new List<Claim>() { new Claim(JwtRegisteredClaimNames.Sub, usuario.UserName!), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()) }; claims.AddRange(roles.Select(role => new Claim(ClaimTypes.Role, role))); var creds = new SigningCredentials(_key, SecurityAlgorithms.HmacSha256); var tokenDescriptor = new SecurityTokenDescriptor { Subject = new ClaimsIdentity(claims), Expires = DateTime.UtcNow.AddMinutes(10), NotBefore = DateTime.UtcNow.AddSeconds(5), Issuer = _config["JWT:Issuer"], SigningCredentials = creds }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); }
测试接口
[HttpGet] [Authorize("SudoRole")] public IActionResult Test() { return Ok("Poto"); }
求助内容
已尝试多种策略仍未解决授权失败问题,寻求问题排查方案及架构优化建议。
内容的提问来源于stack exchange,提问作者yzkael
相关产品推荐
相关产品推荐

