问题描述
我遇到一个问题,当我尝试在控制器中使用[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.Cla@R_502[email protected]aimType = "user_id";
options.Cla@R_502[email protected]aimType = "email";
options.Cla@R_502[email protected]aimType = "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 Cla@R_502_6424@Identity(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": "myadmine[email protected]","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
};