I am getting 403 Forbidden while trying to implement Role based JWT Authorization using .NET Core Web API 3.1 version. Below is how my code looks like:
// API
[HttpGet, Route("GetAll")]
[Authorize(Roles = "Admin")]
public IEnumerable<Users> GetAllUsers(string environment) {}
// JWT Token Generation
public UserDetail GenerateToken(string userName, string password)
{
string key = Configuration["Jwt:Key"];
var issuer = Configuration["Jwt:Issuer"];
var audience = Configuration["Jwt:Audience"];
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
IdentityModelEventSource.ShowPII = true;
//Create a List of Claims, Keep claims name short
var roleClaims = GetRoleClaimsFor(user);
//Create Security Token object by giving required parameters
var token = new JwtSecurityToken(issuer,
audience: audience,
claims: roleClaims,
expires: DateTime.Now.AddMinutes(15),
signingCredentials: credentials);
//Generate JWT Token
var userToken = new JwtSecurityTokenHandler().WriteToken(token);
}
// StartUp.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(opt =>
{
opt.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opt.DefaultChallengeScheme = Configuration["Jwt:Policy"];
}).AddJwtBearer(Configuration["Jwt:Policy"], options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
// JWT Authorization configuration
services.AddAuthorization(auth =>
{
auth.AddPolicy(Configuration["Jwt:Policy"], new AuthorizationPolicyBuilder()
.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
.RequireClaim(ClaimTypes.Name, Configuration["Jwt:RequiredClaim"]).Build());
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseAuthentication();
app.UseAuthorization();
}
private IList<Claim> GetRoleClaimsFor(UserPrincipal user)
{
var roleClaims = new List<Claim>();
UserRoles = new List<string>();
// Pull only groups where user belongs to
PrincipalSearchResult<Principal> groups = user.GetGroups();
// Filter user groups related to GBITs application alone
var gbitsGroups = (from grp in groups
select grp);
// Loop through gbitsGroups and assign the related role
foreach (GroupPrincipal gbitsGrp in gbitsGroups)
{
try
{
// Pull UserGroup related Permissions
var roles = _userGroupPermissionRepository.GetUserGroupPermissionFor(gbitsGrp.Name);
// Loop through UserGroupPermissions to create Claims
foreach (var role in roles)
{
var claim = new Claim(role.UserGroup.GroupName, role.Permission.PermissionName);
roleClaims.Add(claim);
}
// Load Roles collection
IList<string> usrRoles = (from role in roles
select role.Permission.PermissionName).ToList();
UserRoles.AddRange(usrRoles);
}
catch (Exception ex)
{
throw ex;
}
}
return roleClaims;
}
I am able to run and see all the roles as claims from Principal.Identity after validating the token. But the Roles are not working as expected.
RequiredClaimvalue. - Brando Zhang