我正在处理基于声明的身份验证,它运行良好。 现在我想添加角色授权。 我有用户的角色声明(例如“管理员”)
When the IsInRole() method is called, there is a check made to see if the current user has that role. In claims-aware applications, the role is expressed by a role claim type that should be available in the token. The role claim type is expressed using the following URI: http://schemas.microsoft.com/ws/2008/06/identity/claims/role
//Include all claims
//claims is List<Claim> with all claims
var id = new ClaimsIdentity(claims, "Cookies");
Request.GetOwinContext().Authentication.SignIn(id);
如果我检查用户是否在角色中,我会得到 false。虽然我有“管理员”值的角色声明
User.IsInRole("Admin");
同时在我的 api 上授权 attrubute 将不起作用
[Authorize (Roles = "Admin")]
我可能无法理解如何使角色对用户可见。仅在声明列表中包含 Roles 可能还不够?
最佳答案
如果您的服务使用 Windows 身份验证,那么您收到的 IPrincipal.Identity
将是 WindowsPrincipal
类型。这有点误导,但是 WindowsPrincipal.IsInRole()
查找的 ClaimType
并不是您可能合理预期的 ClaimTypes.Role
,而是 ClaimTypes.GroupSid
。
但是,您不应假定当前身份用于指定角色的实际 ClaimType,因为不同类型的身份使用不同的值。相反,您应该引用 ClaimsIdentity.RoleClaimType
属性。
我们按照以下几行实现了 IAuthenticationFilter
:
public Task AuthenticateAsync(HttpAuthenticationContext context, cancellationToken)
{
var principal = context.Principal;
if(principal.Identity is ClaimsIdentity && principal.Identity.IsAuthenticated)
{
var ci = (ClaimsIdentity)principal.Identity;
// get the user's additional roles from somewhere and add Claims
ci.AddClaim(new Claim(ci.RoleClaimType, "MyRole"));
}
}
这允许我们在 ASP.Net Controller 中使用标准的 AuthorizeAttribute 机制。例如
[Authorize(Roles="MyRole")]
public IHttpActionResult Get()
{
//authenticated and authorised code here
}
参见 ClaimsIdentity.RoleClaimType在 MSDN 上进行进一步说明。
请注意:将用户定义的角色添加到 WindowsPrincipal
可能会导致问题。似乎 .Net Framework 4.5 的当前实现(截至 2017 年 4 月)有时会在检查角色时抛出异常,期望角色的详细信息可从 Active Directory 获得。参见 this question另一种方法。
关于c# - 即使声明中存在角色,IsInRole 也会返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35081037/