将授权中的角色评估为 User.IsInRole() 始终 returns false 的正确方法
Proper way to assess Role in Authorization as User.IsInRole() always returns false
关于 User.IsInRole 已经问了很多,但我找不到正确的答案。
我需要通过使用 AuthorizationHandler(通过授权要求)来验证某个角色
我有一个 ASP.NET 核心 2.1 项目,其中包含个人用户帐户。我已经播种了数据库并使用 userManager.AddToRoleAsync
将用户添加到一个(一个角色)角色,是的,数据库显示了用户、角色和他们之间的联系。
我创建了一个 CandidateViewHandler 来控制 View-Contorller 的授权。 IT 看起来如下
public class CandidateViewHandler : AuthorizationHandler<ViewCandidateRequirement, Candidate>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ViewCandidateRequirement requirement, Candidate resource)
{
if (context.User.Identity.IsAuthenticated)
{
if (resource.Email == context.User.FindFirst(ClaimTypes.Name).Value)
{
context.Succeed(requirement);
}
else
{
bool IsAdmin = context.User.IsInRole("Administrator");
bool IsSearch = context.User.IsInRole("Searcher");
if (IsAdmin == true || IsSearch == true)
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
}
然而,IsAdmin
和 IsSearch
总是 return false
。即使在控制器中对其进行测试,结果也保持不变。我应该在 2.1 中使用 Claims
吗?如果是,怎么做?
显然 ASP.NET CORE 2.1 在处理角色方面存在问题:https://github.com/aspnet/Identity/issues/1813,正如该线程中所解释的那样。问题仍然是如何用声明替换角色。
解决方法是回退到 startup
文件中的旧配置:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders()
(所以删除 AddDefaultIdentity<ApplicationUser>.AddRole<ApplicationRole>
并替换为 AddIdentity<AppplicationRole, ApplicationUser>
。现在一切正常。
IMO Charles de M. 提到的讨论实际上表明,角色实际上是对身份的不必要补充。在我看来,将来最好删除 AspNetRoles table (或者至少不再使用它)并直接使用角色作为声明,而不是身份以将角色添加为声明。
将您的角色类型声明 添加到AspNetUserClaims table。默认的 role claim type 是 http://schemas.microsoft.com/ws/2008/06/identity/claims/role
。该类型的任何声明都应自动映射为角色,以便它可以与 IsInRole.
一起使用
您也可以在客户端使用自定义映射:
services.AddAuthentication()
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "role",
NameClaimType = "name",
};
});
旁注,您可能会考虑不再使用角色,因为 asp.net 核心有许多更高级的功能,您可以使用这些功能进行授权。
关于 User.IsInRole 已经问了很多,但我找不到正确的答案。
我需要通过使用 AuthorizationHandler(通过授权要求)来验证某个角色
我有一个 ASP.NET 核心 2.1 项目,其中包含个人用户帐户。我已经播种了数据库并使用 userManager.AddToRoleAsync
将用户添加到一个(一个角色)角色,是的,数据库显示了用户、角色和他们之间的联系。
我创建了一个 CandidateViewHandler 来控制 View-Contorller 的授权。 IT 看起来如下
public class CandidateViewHandler : AuthorizationHandler<ViewCandidateRequirement, Candidate>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ViewCandidateRequirement requirement, Candidate resource)
{
if (context.User.Identity.IsAuthenticated)
{
if (resource.Email == context.User.FindFirst(ClaimTypes.Name).Value)
{
context.Succeed(requirement);
}
else
{
bool IsAdmin = context.User.IsInRole("Administrator");
bool IsSearch = context.User.IsInRole("Searcher");
if (IsAdmin == true || IsSearch == true)
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
}
然而,IsAdmin
和 IsSearch
总是 return false
。即使在控制器中对其进行测试,结果也保持不变。我应该在 2.1 中使用 Claims
吗?如果是,怎么做?
显然 ASP.NET CORE 2.1 在处理角色方面存在问题:https://github.com/aspnet/Identity/issues/1813,正如该线程中所解释的那样。问题仍然是如何用声明替换角色。
解决方法是回退到 startup
文件中的旧配置:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultUI()
.AddDefaultTokenProviders()
(所以删除 AddDefaultIdentity<ApplicationUser>.AddRole<ApplicationRole>
并替换为 AddIdentity<AppplicationRole, ApplicationUser>
。现在一切正常。
IMO Charles de M. 提到的讨论实际上表明,角色实际上是对身份的不必要补充。在我看来,将来最好删除 AspNetRoles table (或者至少不再使用它)并直接使用角色作为声明,而不是身份以将角色添加为声明。
将您的角色类型声明 添加到AspNetUserClaims table。默认的 role claim type 是 http://schemas.microsoft.com/ws/2008/06/identity/claims/role
。该类型的任何声明都应自动映射为角色,以便它可以与 IsInRole.
您也可以在客户端使用自定义映射:
services.AddAuthentication()
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
RoleClaimType = "role",
NameClaimType = "name",
};
});
旁注,您可能会考虑不再使用角色,因为 asp.net 核心有许多更高级的功能,您可以使用这些功能进行授权。