The ClaimsIdentity https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity?view=netcore-3.1允许配置其默认声明类型NameClaimType https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity.nameclaimtype?view=netcore-3.1 and RoleClaimType https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity.roleclaimtype?view=netcore-3.1然后框架的不同部分将其用作处理声明值的快捷方式。
这些快捷方式之一是ClaimsIdentity.Name https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsidentity.name?view=netcore-3.1它仅返回具有配置的默认声明类型的身份的第一个声明的值NameClaimType
。另一个捷径是ClaimsPrincipal.IsInRole https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.isinrole?view=netcore-3.1检查身份是否具有类型声明RoleClaimType
与指定值。
这些名称和角色的可配置声明类型背后的想法是,不存在one每个的标准索赔类型。例如,对于您可能想要使用的名称ClaimTypes.Name https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.claims.claimtypes.name?view=netframework-4.8(哪个值是"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
), or ClaimTypes.NameIdentifier https://learn.microsoft.com/en-us/dotnet/api/system.identitymodel.claims.claimtypes.nameidentifier?view=netframework-4.8(哪个值是"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"
).
如果您有一个与其他非 Microsoft 平台集成的系统,您可能想坚持使用更简单的方法JWT 声明类型 https://www.iana.org/assignments/jwt/jwt.xhtml反而。在那里,您可以使用声明类型"name"
, or "preferred_username"
。同样,在某些设置中,角色声明类型可能只是"role"
.
所以基本上,索赔类型并没有真正标准化,您可能必须在不同的应用程序和场景中选择不同的类型。没关系。但由于 .NET 类型中有一些实用程序,因此如果您希望这些实用程序正常工作,您可能必须指定正在使用的名称和角色声明类型。
至于索赔检索,正如您所见,您不仅可以访问属性。相反,有一些实用方法允许您查询声明。最常见的是ClaimsPrincipal.FindFirst https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.findfirst?view=netcore-3.1它返回特定类型的第一个声明。如果你只是想检查是否存在,你也可以使用ClaimsPrincipal.HasClaim https://learn.microsoft.com/en-us/dotnet/api/system.security.claims.claimsprincipal.hasclaim?view=netcore-3.1.
在ASP.NET Core内部,你还有非常有用的扩展方法ClaimsPrincipal.FindFirstValue https://learn.microsoft.com/de-de/dotnet/api/system.security.claims.principalextensions.findfirstvalue?view=aspnetcore-3.1它将仅返回特定声明类型的声明值。这可能是您大部分时间都会使用的。
作为个人建议,我还会考虑创建您自己的一组特定于应用程序的扩展方法ClaimsPrincipal
它允许您直接检索特定于您的应用程序的声明类型的值。这还使您能够直接将声明值解析为您想要的任何类型(因为声明仅基于字符串)。例如,这可能如下所示:
public static class ClaimsPrincipalExtensions
{
public static string GetName(this ClaimsPrincipal user)
=> user.FindFirstValue(ClaimTypes.Name);
public static string GetRole(this ClaimsPrincipal user)
=> user.FindFirstValue(ClaimTypes.Role);
public static int GetId(this ClaimsPrincipal user)
=> int.Parse(user.FindFirstValue("id"));
}
然后就可以直接在上面使用这些扩展方法了User
整个 ASP.NET Core 中存在的对象,例如在视图或控制器中:
<div class="user-info">
<strong>@User.GetName() (@User.GetId())</strong>
Current role: @User.GetRole()
</div>
最后一点:通常,一个身份应该能够同时担任多个角色。这就是为什么该框架没有单一的Role
属性来获得single角色声称有价值,但给你一个IsInRole
方法来根据用户所在的角色集检查单个角色值。当然,这只是默认假设:如果您的应用程序仅使用单个角色值,那么将角色声明视为任何角色声明都是完全可以的。您只期望单个值的其他声明。