I have trouble with understanding Roles
in Identity Core
My AccountController
looks like this, I added Roles
in claims in GenerateJWTToken
method:
[HttpPost("Login")]
public async Task<object> Login([FromBody] LoginBindingModel model)
{
var result = await this.signInManager.PasswordSignInAsync(model.UserName, model.Password, false, false);
if (result.Succeeded)
{
var appUser = this.userManager.Users.SingleOrDefault(r => r.UserName == model.UserName);
return await GenerateJwtToken(model.UserName, appUser);
}
throw new ApplicationException("INVALID_LOGIN_ATTEMPT");
}
[HttpPost("Register")]
public async Task<object> Register([FromBody] RegistrationBindingModel model)
{
var user = new ApplicationUser
{
UserName = model.UserName,
Email = model.Email,
FirstName = model.FirstName,
LastName = model.LastName
};
var result = await this.userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await this.signInManager.SignInAsync(user, false);
return await this.GenerateJwtToken(model.UserName, user);
}
throw new ApplicationException("UNKNOWN_ERROR");
}
private async Task<object> GenerateJwtToken(string userName, IdentityUser user)
{
var claims = new List<Claim>
{
new Claim(JwtRegisteredClaimNames.Sub, userName),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.NameIdentifier, user.Id),
new Claim(ClaimTypes.Role, Role.Viewer.ToString()),
new Claim(ClaimTypes.Role, Role.Developer.ToString()),
new Claim(ClaimTypes.Role, Role.Manager.ToString())
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(this.configuration["JwtKey"]));
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expires = DateTime.Now.AddDays(Convert.ToDouble(this.configuration["JwtExpireDays"]));
var token = new JwtSecurityToken(
this.configuration["JwtIssuer"],
this.configuration["JwtIssuer"],
claims,
expires: expires,
signingCredentials: creds);
return new JwtSecurityTokenHandler().WriteToken(token);
}
From this code my token works perfectly with [Authorize]
controller's attribute.
My question is, in which step add role
to my registered user
to use (for example) [Authorize("Admin")]
? How to save role
to database?
[Route("api/[controller]")]
[Authorize] //in this form it works ok, but how to add roles to it with JWT Token?
//how to register user to role and get this role to JWT Token?
[ApiController]
public class DefaultController : ControllerBase
My ApplicationUser
:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
And Enum for Roles
:
public enum Role
{
Viewer,
Developer,
Manager
}
How to save information about user role to Identity Database and while login get that role to properly working [Authorize]
attribute?
EDIT:
What i want to do is to store Roles
like in my enums in User. I want to register user as Developer
, Manager
etc. I belive i can do it by ApplicationUser
and add Role
property, but from it i couldnt get authorization by attribute [Authorization(role)]
You don't need to use IdentityUser and identity database in your case, you are using JWT. Create your User
model with defined Roles
property and simple persist it in the database. Like:
public class User
{
public string FirstName { get; set; }
public string LastName { get; set; }
public Role Role { get; set; }
}
public enum Role
{
Viewer,
Developer,
Manager
}
the token:
var user = // ...
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(your_seccret_key);
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, user.FirstName),
new Claim(ClaimTypes.Name, user.LastName),
new Claim(ClaimTypes.Role, user.Role)
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key),SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
user.Token = tokenHandler.WriteToken(token);
controller method:
[Authorize(Roles = Role.Developer)]
[HttpGet("GetSomethingForAuthorizedOnly")]
public async Task<object> GetSomething()
{
// .... todo
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With