Home > Net >  What is the Problems of my Code in Claim base Authorization ASP.NET CORE WEB API?
What is the Problems of my Code in Claim base Authorization ASP.NET CORE WEB API?

Time:11-29

I want to use claim base Authorization in ASP.NET CORE Web API, I think my code is true but, it does not work for me and gives me the error 403 forbidden however I use the Right Token which has the right claim value in my AspNetUserClaims table here is my Program.cs code

//Get Connection String
builder.Services.AddDbContext<AppDbContext>(opts =>
               opts.UseNpgsql(builder.Configuration["connection:connectionString"]));


builder.Services.Configure<ApplicationSettings>(builder.Configuration.GetSection("ApplicationSettings"));

builder.Services.AddMvc();


builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<AppDbContext>();

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("VIEW",
        policy => policy.RequireClaim("VIEW"));
});

builder.Services.Configure<IdentityOptions>(options =>
options.User.RequireUniqueEmail = true);



//JWT Token Setup
var key = Encoding.UTF8.GetBytes(builder.Configuration["ApplicationSettings:JWT_Secret"]);

builder.Services.AddAuthentication(x =>
{
    x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(x => {
    x.RequireHttpsMetadata = false;
    x.SaveToken = false;
    x.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        ValidateIssuerSigningKey = true,
        IssuerSigningKey = new SymmetricSecurityKey(key),
        ValidateIssuer = false,
        ValidateAudience = false,
        ClockSkew = TimeSpan.Zero
    };
});

here is my UsersLoginController when the user login, this controller generates the Token after successful login

        [HttpPost]
        [Route("Login")]
   
        public async Task<IActionResult> Login(LoginModel model)
        {
            var user = await _userManager.FindByNameAsync(model.UserName);
            if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
            {
                //Get role assigned to the user
                var role = await _userManager.GetRolesAsync(user);
                IdentityOptions _options = new IdentityOptions();

                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim("UserID",user.Id.ToString()),
                        new Claim(_options.ClaimsIdentity.RoleClaimType,role.FirstOrDefault())
                    }),
                    Expires = DateTime.UtcNow.AddDays(1),
                    SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_appSettings.JWT_Secret)), SecurityAlgorithms.HmacSha256Signature)
                };
                var tokenHandler = new JwtSecurityTokenHandler();
                var securityToken = tokenHandler.CreateToken(tokenDescriptor);
                var token = tokenHandler.WriteToken(securityToken);
                return Ok(new { token });
            }
            else
                return BadRequest(new { message = "Username or password is incorrect." });
        }
    }

here is my UsersProfileDetailsController

        [HttpGet]
        [Authorize(Policy = "VIEW")]
        
        public async Task<Object> GetUserProfile()
        {
            string userId = User.Claims.First(c => c.Type == "UserID").Value;
            var user = await _userManager.FindByIdAsync(userId);
            var role = await _userManager.GetRolesAsync(user);
            return new
            {
                user.Id,
                user.FirstName,
                user.LastName,
                user.Email,
                user.UserName,
                user.PhotoPath,
                role,
    
            };
        }

Now when I login with Admin User which has the right Claimvalue VIEW in the Table AspNetUserClaims, it generates the Token for me but when I use this Token to access UserDetails from UsersProfileDetailsController it gives me the code 403 forbidden. Can anyone help me with how to implement Claims base Authorization and what are my problems? I use Postman for testing.

CodePudding user response:

because you configured authoriztion as below:

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("VIEW",
        policy => policy.RequireClaim("VIEW"));
});

If you Press F12 and go to definition,you'll find the explaination of the method enter image description here

you added [Authorize(Policy = "VIEW")] on your controller, if you want authorize successfully, when you generate the token,you have to add the claim VIEW

Subject = new ClaimsIdentity(new Claim[]
                    {
                        new Claim("UserID",user.Id.ToString()),
                        //add a new claim named View here
                        new Claim("View",.......),
                        new Claim(_options.ClaimsIdentity.RoleClaimType,role.FirstOrDefault())
                    }),
  • Related