cia*_*anj 11 c# authentication claims-based-identity wif asp.net-identity
TL; DR.我写这篇文章是因为我没有找到关于这种特定行为的文档,并且部分希望有人可以确认(或否认)这是正确的方法(总结使用.Identities ),这可能有助于其他人的Google搜索..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);
Run Code Online (Sandbox Code Playgroud)
后来一些代码"检查"这些声明,看起来像:
((ClaimsPrincipal)context.Authentication.User).HasClaim(permission.ClaimType, permission.ClaimValue);
Run Code Online (Sandbox Code Playgroud)
这段代码一直很好用,直到一些明亮的火花(我)注意到我们的web.config缺少一个<authentication mode="None">元素.但是,只要我将其置于身份验证逻辑中就会进入地狱(特别是'HasClaim'调用不再返回true).
我们最终将故障追溯到从WindowsPrincipal实例变为a 的Principal类型GenericPrincipal.特别是通过源代码阅读我可以看到,当GenericPrincipal Identity在构造函数中传递时,它的一个克隆被用作context.Authentication.User 这里的Identities属性中的一个条目.
然后,'HasClaim'方法迭代Identities集合,但忽略单个'Identity'属性,因此我们的代码正在操纵(在这种情况下GenericPrincipal)Identity的声明的错误实例.
Sooooo考虑到这一点我在互联网上有一个外观,我注意到当其他人操纵声明我看到代码如:var id = ClaimsPrincipal.Current.Identities.First(); 或ClaimsIdentity aspNetIdentity = principal.Identities.FirstOrDefault(...)
这将适用于所有人; GenericPrincipal,WindowsPrincipal和ClaimsPrincipal实例(后两个因为第一个实例Identities通常是一样的Identity属性和第一因为"HasClaim"方法查询此相同的集合.)
我是否错过了备忘录,它说我们需要这样做(我在微软的API文档中看不到任何评论)?