我在.Net 4.6.2 / MVC5中更新ASP.Net Identity 2.2.1的声明时遇到问题。 更新声明后,它通常会向浏览器发送更新的cookie,一切正常,但有时没有设置cookie标头发送到浏览器。
我无法确定何时发生任何模式,而不是在发生故障时,服务器正在发送
Persistent-Auth: true
会话中每个响应的http标头值。我不知道导致此标头值设置的原因,有时会出现在会话中间,一旦开始发送,它将在会话的剩余时间内发送,尝试更新声明将永远不会再次工作该会议。
据我所知,我在每次调用ASP.Net标识时都将isPersistent参数硬编码为false,我看不到任何可能与此标题相关的内容。
我用于更新声明的代码是
public static void UpdateClaims(List<Claim> claims)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var newIdentity = new ClaimsIdentity(HttpContext.Current.User.Identity);
foreach (Claim claim in claims)
{
Claim oldClaim = newIdentity.FindFirst(claim.Type);
if (oldClaim != null && oldClaim.Type != "")
{
newIdentity.RemoveClaim(oldClaim);
}
newIdentity.AddClaim(claim);
}
authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant
(new ClaimsPrincipal(newIdentity), new AuthenticationProperties { IsPersistent = false });
}
这是从MVC操作方法调用的。
有没有人有任何可能出错的建议,甚至只是在哪里寻找起点?我不知道是什么导致了持久性身份验证标头,但它看起来与问题有关;无论是问题的原因还是症状,我都不知道。
我使用ASP.Net Identity 2.2.1和.Net 4.6.2。 我在Windows Server 2012R2上运行,问题似乎发生在IE11,Chrome和Firefox上。 我使用Fiddler 4.6.3查看http标头/响应。
更新: 我注意到只有在启用Windows身份验证时才会出现问题。我的服务器有一个允许用户名/密码,Windows身份验证或两者的设置(用户可以选择使用用户名/密码以其他用户身份登录)。当使用windows auth时,我最初使用Windows对用户进行身份验证,然后设置一个cookie,然后我将其用于会话中的所有未来请求。 如果禁用了Windows身份验证,则更新此类声明始终有效。如果启用了Windows身份验证,则更新声明通常有效。
答案 0 :(得分:14)
首先,你将两种不同的东西混为一谈,虽然这是可以理解的,因为它们的名字相似。 IsPeristent
设置确定cookie是会话cookie还是持久cookie。换句话说:它确定在浏览器关闭时或在某个预定时间,无论浏览器是否关闭,cookie是否会过期。
Persistent-Auth
标头是一个优化标头,通知客户端它不一定需要授权每个请求。它与IsPersistent
标志无关。
声明在登录时设置。期。如果您需要更新声明,则必须签署用户并重新签名。这可以通过编程方式完成(即无需用户干预),但必须完成。换句话说,如果您需要更改声明,并且您需要在下一个请求中提供该更改,那么请按照以下步骤进行:
身份2.0
AuthenticationManager.SignOut();
await SignInManager.SignInAsync(user);
Identity 3.0
await SignInManager.RefreshSignInAsync(user);
答案 1 :(得分:4)
而不是
MyParserClass
你应该使用
authenticationManager.AuthenticationResponseGrant =
new AuthenticationResponseGrant(new ClaimsPrincipal(newIdentity),
new AuthenticationProperties { IsPersistent = false });
答案 2 :(得分:1)
我发现了问题。它在尝试更新声明时使用了错误的标识。在我的场景中,有两个身份对象,一个用于Windows身份验证,另一个用于cookie身份验证。在大多数情况下,Pod
获取cookie身份验证对象(具有声明的那个)但偶尔会给我一个Windows身份验证对象,因此当我尝试更新声明时,它没有做任何事。
问题通过替换
解决了HttpContext.Current.User.Identity
与
var newIdentity = new ClaimsIdentity(HttpContext.Current.User.Identity);
现在似乎可以稳定地工作而无需再次退出/退回。
我想当OWin认为Windows身份验证是主要身份时,会发送ClaimsIdentity oldIdentity = claimsPrincipal.Identities.FirstOrDefault(i => i.AuthenticationType == "ApplicationCookie");
var newIdentity = new ClaimsIdentity(oldIdentity);
http标头,这就是为什么它的存在与无法更新声明相关的原因。
答案 3 :(得分:0)
我认为在我们的案例中,这是ApplicationUserManager的错误/长期IoC生命周期/“作用域”,而且角色管理器也可能是相同的。