如何解决带有JWT的.NET Core 3.1基于角色的授权禁止返回403
我遇到一个问题,当我尝试在控制器中使用[Authorize(Roles = "Administrator")]
时,它总是返回403
。我正在使用身份和JWT令牌。这是我的Startup.cs
。我在app.UseAuthentication()
中同时呼叫app.UseAuthorization()
和ConfigureServices()
,但每次返回403
public void ConfigureServices(IServiceCollection services)
{
...
services.AddIdentity<User,Role>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredUniqueChars = 0;
options.Password.RequiredLength = 6;
options.ClaimsIdentity.UserIdClaimType = "user_id";
options.ClaimsIdentity.UserNameClaimType = "email";
options.ClaimsIdentity.RoleClaimType = "user_role";
})
.AddRoles<Role>()
.AddEntityFrameworkStores<MyDbContext>()
.AddDefaultTokenProviders();
var key = Encoding.UTF8.GetBytes(Configuration["ApplicationSettings:JwtKey"].ToString());
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => {
options.RequireHttpsMetadata = false;
options.SaveToken = false;
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,ValidateAudience = false,ValidateIssuer = false,IssuerSigningKey = new SymmetricSecurityKey(key),ClockSkew = TimeSpan.Zero
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
context.HttpContext.Response.StatusCode = StatusCodes.Status401Unauthorized;
return Task.CompletedTask;
}
};
});
services.AddControllers()
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});
...
}
public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
这是我创建令牌的方式
private async Task<string> GenerateToken(DataModelUser user)
{
var key = Encoding.UTF8.GetBytes(_appSettings.JwtKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim("user_role",user.Role.ToString()),new Claim("user_id",user.Id.ToString()),new Claim("email",user.Email)
}),Expires = DateTime.UtcNow.AddDays(1),SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),SecurityAlgorithms.HmacSha256Signature)
};
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(securityToken);
}
我在控制器上添加了这样的内容
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ProfileController : ControllerBase
{
[HttpGet]
[Authorize(Roles = "Administrator")]
public async Task<IActionResult> Get()
{
return Ok();
}
}
这是我的JWT令牌有效载荷!
{
"user_role": "Administrator","user_id": "5a6333f1-9696-4b1c-a8f8-04619ebd686d","name": "Admin Admin","completed_profile": "False","email": "myadminemail@gmail.com","nbf": 1597147248,"exp": 1597233648,"iat": 1597147248
}
解决方法
我遇到了类似的问题,我通过在TokenValidationParameter中添加RoleClaimType和NameClaimType来解决了该问题:
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,ValidateAudience = false,ValidateIssuer = false,IssuerSigningKey = new SymmetricSecurityKey(key),ClockSkew = TimeSpan.Zero,RoleClaimType = IdentityModel.JwtClaimTypes.Role,NameClaimType = IdentityModel.JwtClaimTypes.Name
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。