Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JWT authorization with roles in Identity Core

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)]

like image 889
michasaucer Avatar asked Oct 19 '25 16:10

michasaucer


1 Answers

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
}
like image 149
Milenko Jevremovic Avatar answered Oct 22 '25 05:10

Milenko Jevremovic



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!