TL; DR。我写这篇文章是因为我找不到有关这一特定行为的文档,部分希望有人可以确认(或否认)这是正确的方法(总结使用.Identities.First()not .Identity!) ... 所以,我的团队有一些代码可以操纵“声明”(如果你愿意,可以声称转换),看起来像是:
var claimsIdentity = ((ClaimsIdentity)context.Authentication.User.Identity);
var transformedClaims = await this.Transformer.Transform(dbContext, claimsIdentity.Claims);
foreach (var claim in claimsIdentity.Claims.ToList())
{
claimsIdentity.RemoveClaim(claim);
}
claimsIdentity.AddClaims(transformedClaims);
后来有些代码“检查”这些声明,如下所示:
((ClaimsPrincipal)context.Authentication.User).HasClaim(permission.ClaimType, permission.ClaimValue);
这段代码一直很好用,直到一些明亮的火花(我)注意到我们的web.config缺少一个<authentication mode="None">
元素。但是,只要我将其置于身份验证逻辑中就会进入地狱(特别是'HasClaim'调用不再返回true。)
我们最终将故障跟踪到从WindowsPrincipal
实例更改为GenericPrincipal
的Principal类型。 具体阅读源代码我可以看到,当GenericPrincipal在构造函数中传递Identity
时, clone 将其用作Identities属性中的一个条目context.Authentication.User
here的内容。
然后'HasClaim'方法迭代Identities集合,但忽略单个'Identity'属性,因此我们的代码正在操纵(在GenericPrincipal
的情况下)错误的实例身份的主张。
Sooooo考虑到这一点我在互联网上有一个看起来很好看,我注意到当其他人操纵声明时,我看到的代码如下: var id = ClaimsPrincipal.Current.Identities.First(); 要么 ClaimsIdentity aspNetIdentity = principal.Identities.FirstOrDefault(...)
这将适用于所有人; GenericPrincipal
,WindowsPrincipal
和ClaimsPrincipal
个实例(后两个实例,因为Identities
的第一个实例通常与Identity
属性相同,第一个实例与第一个实例相同,因为'HasClaim'方法查询同一个集合。)
我是否错过了我们需要这样做的备忘录(我在微软的API文档中看不到任何评论)?