【发布时间】:2020-12-01 00:23:16
【问题描述】:
我遇到了一个问题,当我尝试在我的控制器中使用 [Authorize(Roles = "Administrator")] 时,它总是返回 403。我正在使用身份和 JWT 令牌。这是我的Startup.cs。我在ConfigureServices() 中同时调用app.UseAuthentication() 和app.UseAuthorization(),但每次返回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
}
【问题讨论】:
-
嗨@Erlan。您是在检查角色“管理员”还是“管理员”?由于在上面的帖子中您提到要检查“管理员”,而在控制器示例中您要检查“管理员”。
-
@ThomasLuijken 抱歉,写错了,因为我正在检查
Administrator,现在编辑问题! -
@Erlan,好的,感谢您的更新。只是为了检查我们没有遗漏任何明显的东西。我希望在这两个地方设置 'user_role' 声明可以解决问题,但显然它没有。您能否将 JWT 令牌中的一部分有效负载也上传到票证中,以便我们可以看到您的令牌的实际内容是什么样的?您可以在jwt.io 处粘贴访问令牌以查看实际有效负载。
-
@ThomasLuijken 是的,当然,刚刚编辑了问题并从 JWT 令牌添加了有效负载。
标签: c# .net-core jwt asp.net-core-3.1 asp.net-core-identity