【发布时间】:2020-09-20 16:15:47
【问题描述】:
我在尝试使用 .NET Core Web API 3.1 版本实现基于角色的 JWT 授权时收到 403 Forbidden。下面是我的代码的样子:
// 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;
}
验证令牌后,我能够运行并查看所有角色作为 Principal.Identity 的声明。但是角色没有按预期工作。
【问题讨论】:
-
能否请您分享一下GetRoleClaimsFor方法的详细代码,您似乎没有添加声明角色或者您错过了
RequiredClaim值。 -
谢谢白兰度。我已经用 GetRoleClaimsFor 方法修改了代码 sn-p(请参阅它的底部)。如果您需要更多详细信息,请告诉我。
-
白兰度。现在通过将角色声明类型更改为“ClaimsType.Role”一切正常
-
是的,我也猜你可能使用了错误的角色声明类型。我建议您可以将其回复为答案并标记它。这样其他面临相同错误的人可以更轻松地找到问题。
标签: c# asp.net-core .net-core asp.net-core-webapi