skip to Main Content

I follow the tutorial link below.

https://fullstackmark.com/post/13/jwt-authentication-with-aspnet-core-2-web-api-angular-5-net-core-identity-and-facebook-login

I am trying to understand how it works and I want to use role-based authentication using this token. so I made another policy in the Startup.cs file as below.

And I tried to use it like [Authorize(Policy = "admin")] or [Authorize(Policy = "ApiUser")]in the controller but every time I try I get unauthenticated using postman.
What am I missing? how to make roles-based authentication based on the tutorial?

Startup

services.AddAuthorization(options =>
{
    options.AddPolicy("ApiUser", policy => policy.RequireClaim(Constants.Strings.JwtClaimIdentifiers.Rol, Constants.Strings.JwtClaims.ApiAccess));
});
services.AddAuthorization(options =>
    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
);


Auth Controller

// POST api/auth/login
[HttpPost("login")]
public async Task<IActionResult> Post([FromBody]CredentialsViewModel credentials)
{
    if (!ModelState.IsValid)
    {
        return BadRequest(ModelState);
    }

    var identity = await GetClaimsIdentity(credentials.UserName, credentials.Password);



    if (identity == null)
    {
        //return null;
        return BadRequest(Error.AddErrorToModelState("login_failure", "Invalid username or password.", ModelState));
    }
    var id = identity.Claims.Single(c => c.Type == "id").Value; 
    var user = await _userManager.FindByIdAsync(id);
    IList<string> role = await _userManager.GetRolesAsync(user);
    var jwt = await Tokens.GenerateJwt(identity, role[0], _jwtFactory, credentials.UserName, _jwtOptions, new JsonSerializerSettings { Formatting = Formatting.Indented });


    return new OkObjectResult(jwt);

}

I tried with all method and none of them working

[Authorize(Policy = "ApiUser")]
[HttpGet("getPolicy")]
public string GetPolicy()
{
    return "policyWorking";
}
[Authorize(Roles = "admin")]
[HttpGet("getAdmin")]
public string GetAdmin()
{
    return "adminWorking";
}
[Authorize ]
[HttpGet("getAuthorize")]
public string GetAuthorize()
{
    return "normal authorize Working";
}

2

Answers


  1. I’ve made mine using this tutorial.

    It also works with .Net Core 3.1.

    @Update

    I’m using policies for that:

    services.AddAuthorization(options => {
        options.AddPolicy(Policies.RequireAny, policy =>
            policy.RequireClaim(JwtClaimTypes.Role, Enum.GetNames(typeof(AvailableRoles))));
        options.AddPolicy(Policies.RequireAdmin, policy =>
            policy.RequireClaim(JwtClaimTypes.Role,
                AvailableRoles.Admin.ToString()));
    });
    

    And in Controller

    [HttpDelete("{id:int:min(1)}")]
    [Authorize(Policy = Policies.RequireAdmin)]
    public async Task<IActionResult> Delete(int id) {
        // CODE
        return Ok();
    }
    

    and in creating JWT Token:

    
    // Other claims and code...
    
    claims.Add(new Claim(JwtClaimTypes.Role, roles[0]))
    var token = new JwtSecurityToken(
        issuer:_appSettings.AppUrl,
        audience:_appSettings.AppUrl,
        claims: claims,
        expires: expires,
        signingCredentials: credentials
    );
    
    return new JwtSecurityTokenHandler().WriteToken(token);
    
    Login or Signup to reply.
  2. Firstly,be sure you have add json string in your appsettings.json otherwise you would always get 401 unauthorized:

    "JwtIssuerOptions": {
        "Issuer": "webApi",
        "Audience": "http://localhost:5000/"
    }
    

    What am I missing? how to make roles-based authentication based on the tutorial?

    1.If you want to use the following way to register the service:

    services.AddAuthorization(options =>
        options.AddPolicy("admin", policy => policy.RequireRole("admin"))
    );
    

    The authorize attribute should be like below:

    [Authorize(Policy  = "admin")]
    

    2.If you want to use the following way:

    [Authorize(Roles = "admin")]
    

    You need to remove the service from Startup.cs:

    //services.AddAuthorization(options =>
    //    options.AddPolicy("admin", policy => policy.RequireRole("admin"))
    //);
    

    Then,don’t forget to add claim with role in JwtFactory.GenerateEncodedToken like below:

    public async Task<string> GenerateEncodedToken(string userName, ClaimsIdentity identity)
    {
        var claims = new[]
        {
                new Claim(JwtRegisteredClaimNames.Sub, userName),
                new Claim(JwtRegisteredClaimNames.Jti, await _jwtOptions.JtiGenerator()),
                new Claim(JwtRegisteredClaimNames.Iat, ToUnixEpochDate(_jwtOptions.IssuedAt).ToString(), ClaimValueTypes.Integer64),
                identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Rol),
                identity.FindFirst(Helpers.Constants.Strings.JwtClaimIdentifiers.Id),
                new Claim(ClaimTypes.Role,"admin")
        };
            //...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search