问题
How I can authenticate user by claims, which contains in user roles?
In Startup.cs:
services.AddAuthorization(options => {
options.AddPolicy("CanEdit", policy => policy.RequireClaim("CanEdit"));
});
And in login controller I have:
private async ValueTask<JwtSecurityToken> GetJwtSecurityToken(ApplicationUser user){
//var totalClaims = new List<Claim>();
//var userRoles = await _userManager.GetRolesAsync(user);
//foreach (var role in userRoles) {
// var roleClaims = await _roleManager.GetClaimsAsync(await _roleManager.Roles.SingleAsync(r => r.Name.Equals(role)));
// totalClaims.AddRange(roleClaims);
//}
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
new Claim(JwtRegisteredClaimNames.Email, user.Email)
};
return new JwtSecurityToken(
_configuration["Token:Issuer"],
_configuration["Token:Audience"],
//totalClaims,
claims
expires: DateTime.UtcNow.AddHours(12),
signingCredentials: new SigningCredentials(
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Token:Key"])),
SecurityAlgorithms.HmacSha256)
);
}
Method policy.RequireClaim search claims in token, not in role.
When I uncomment the lines, it works. Is this a good solution?
回答1:
To add roles to claims, you'll need use claim type Role, like so:
var rolesList = new List<string>
{
"Admin",
"SuperUser",
"Etc..."
};
foreach (var role in rolesList)
{
claims.Add(new Claim(ClaimTypes.Role, role));
}
NB:- when creating token ensure claims are added.
var Token = new JwtSecurityToken(
issuer: "localhost",
audience: "localhost",
expires: DateTime.Now.AddMinutes(10),
claims:claims //claims added to token here!
signingCredentials: Creds);
return new JwtSecurityTokenHandler().WriteToken(Token);
}
That's it, now you can test if the token contains the role "Admin" via the Authorize attribute.
[Authorize(Roles="Admin")]
NB:- To test against multiple roles (the token contains the claim "Admin" or "SuperUser")
[Authorize(Roles="Admin","SuperUser")]
EDIT as pointed out by @gentiane below
[Authorize(Roles="Admin,SuperUser")]
来源:https://stackoverflow.com/questions/49426781/jwt-authentication-by-role-claims-in-asp-net-core-identity