ASP.NET身份验证中的“基于角色”的声明

25

我明白我可以使用声明(claims)来陈述关于用户的信息:

var claims = new List<Claim>();
claims.Add(new Claim(ClaimTypes.Name, "Peter"));
claims.Add(new Claim(ClaimTypes.Email, "peter@domain.com"));

但是我应该如何存储“基于角色”的声明? 比如:

用户是超级管理员。

claims.Add(new Claim("IsSuperAdmin, "true"));

使用声明语句,如何在不使用"value"参数为"true"的情况下表达同样的意思。

3个回答

39

这已经由框架为您完成。当用户登录时,所有用户角色都会作为声明添加,声明类型为ClaimTypes.Role,值为角色名称。

当您执行IPrincipal.IsInRole("SuperAdmin")时,框架实际上会检查用户是否具有类型为ClaimTypes.Role且值为SuperAdmin的声明。

因此,不需要进行任何特殊操作。只需将用户添加到角色即可。


4
我需要指出的是,IPrincipal.IsInRole("xx") 方法在查找匹配声明时,不一定使用 ClaimTypes.Role。例如,在进行 Windows 身份验证后,您可能会收到 WindowsPrincipal,它实际上使用 ClaimTypes.GroupSid 来指定角色。因此,请使用 ClaimsIdentity.RoleClaimType 属性来代替。 - Rob
1
@Rob 上下文是至关重要的。IsInRoleIPrincipal 接口的一部分(https://referencesource.microsoft.com/#mscorlib/system/security/principal/iprincipal.cs,c78f7d29e063c03c,references),任何实现它的对象都可以执行其功能。在这里,我们谈论的是 ClaimsPrincipal(https://referencesource.microsoft.com/#mscorlib/system/security/claims/ClaimsPrincipal.cs,765),它使用声明来定义角色。如果您在 MVC 应用程序中的身份框架中获得了 WindowsPrincipal,那么您正在做一些非常错误的事情。 - trailmax
1
@trailmax WindowsPrincipal 派生自 .Net 4.5 中的 ClaimsPrincipal,我相信如果您配置应用程序使用 Windows 集成身份验证,则在 ASP.Net Web API(和 MVC?)中将收到 WindowsPrincipal。但这里的重点是使用特定的 ClaimTypes.Role 来驱动 ClaimsPrincipal.IsInRole 是不正确的。请参见 ClaimsPrincipal.IsInRole - Rob
1
@Rob 好的,我只是跟踪了源代码到这一行:https://referencesource.microsoft.com/#mscorlib/system/security/claims/ClaimsIdentity.cs,72,因此才有了我的参考。 - trailmax
3
嗨@trailmax。这有点玄学,但请注意ClaimsPrincipal.IsInRole()使用属性RoleClaimType来测试包含的标识是否具有所需的声明。您可以在ClaimsIdentity的参考源代码中看到,该属性的后备字段默认为ClaimsType.Role,但是WindowsIdentity构造函数将ClaimTypes.GroupSid传递给此字段。我不知道其根本原因,但这就是为什么最好使用RoleClaimType属性的原因。 - Rob
显示剩余4条评论

21
您可以使用声明类型 Role 来存储角色。
claims.Add(new Claim(ClaimTypes.Role, "SuperAdmin"));

3
我之前在上面发表了这个评论,但它同样适用于这里:在添加角色时,使用ClaimsIdentity.RoleClaimType属性会更可靠。 - Rob
多个角色怎么办? - Alexander Christov
逗号分隔?同一类型的多个声明?其他? - Alexander Christov
2
@AlexanderChristov 同一类型的多个声明。 - dpant

3

在具有ClaimsType.Role类型的声明中,您需要指定角色,然后在ClaimsIdentity中指定包含该角色的声明类型,如下所示。

var claimsIdentity = new ClaimsIdentity(new[]
{
    new Claim(ClaimTypes.Email, "peter@domain.com"),
    new Claim(ClaimTypes.Name, "Peter"),
    new Claim(ClaimTypes.Role, "SuperAdmin"),
},
"ApplicationCookie", ClaimTypes.Email, ClaimTypes.Role);

这将允许您在控制器中使用[Authorize(Roles = "SuperAdmin")]属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接