2017-01-31 45 views
0

我在更新.NET .Net 4.6.2/MVC5中的ASP.Net Identity 2.2.1声明时遇到问题。 更新索赔后,它通常会发送一个更新的cookie到浏览器,一切正常,但有时没有设置cookie头被发送到浏览器。ASP.NET身份:在修改声明后没有更新cookie

我已经无法找出任何图案,当它发生时,它失败以外的其他的服务器发送在会议圆满响应

Persistent-Auth: true 

HTTP标头值。我不知道是什么导致这个头值被设置,它有时会出现在会话中,一旦它开始发送它,它将被发送到会话的其余部分,并尝试更新声明将永远不会再为该会话工作。

据我所见,我已经硬编码isPersistent参数在每次调用ASP.Net身份时都是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动作方法调用。

有没有人有什么建议可能会出错或甚至只是一个起点在哪里看?我不知道是什么导致了这个persistent-auth头,但它看起来与问题有关;无论是问题的原因还是症状,我都不知道。

我使用ASP.Net Identity 2.2.1与.Net 4.6.2。 我在Windows Server 2012R2上运行,并且问题似乎与IE11,Chrome和Firefox一起发生。 我正在使用Fiddler 4.6.3来查看http标题/响应。

更新: 我注意到,它似乎只在启用Windows身份验证时出错。我的服务器有一个设置,允许用户名/密码,Windows身份验证或两者(用户可以选择使用用户名/密码作为不同的用户登录)。当使用Windows身份验证时,我最初使用Windows对用户进行身份验证,然后设置一个cookie,然后将该cookie用于会话中的所有未来请求。 如果禁用了Windows身份验证,则更新这样的声明总是有效。如果启用了Windows身份验证,更新声明通常的作品。

+0

我认为你必须退出并登录才能更新cookie中的声明 – Saravanan

回答

1

我发现这个问题。它在尝试更新索赔时使用了错误的身份。在我的场景中,有两个身份对象,一个用于Windows身份验证,另一个用于cookie身份验证。在大多数情况下,HttpContext.Current.User.Identity获取cookie身份验证对象(这是具有声明的身份验证对象),但偶尔会向我提供Windows身份验证对象,因此当我尝试更新声明时,它没有执行任何操作。

问题是由与

ClaimsIdentity oldIdentity = principal.Identities.FirstOrDefault(i => i.AuthenticationType == "ApplicationCookie"); 
var newIdentity = new ClaimsIdentity(oldIdentity); 

更换

var newIdentity = new ClaimsIdentity(HttpContext.Current.User.Identity); 

解决它现在似乎无需退出/返回再次扎实工作。

我猜想012.http头被发送时,OWin认为Windows身份验证是主要身份,这就是为什么它的存在与无法更新索赔相关联。

8

首先,你将两个不同的东西混合在一起,虽然它是可以理解的,因为它们的命名方式相似。 IsPeristent设置确定cookie是否是会话cookie或持久性cookie。换句话说:它决定了当浏览器关闭或在某个预定时间,cookie是否过期,无论浏览器是否关闭。

Persistent-Auth头是一个优化头,通知客户端它不一定需要授权每个请求。它与IsPersistent标志无关。

声明在登录时设置。期。如果您需要更新索赔,则必须签署用户并签名。这可以通过编程方式完成(即无需用户干预),但必须完成。换句话说,如果你需要改变一个要求,你需要的是改变在下一个请求可用,那么你就跟着它具有:

身份2.0

AuthenticationManager.SignOut(); 
await SignInManager.SignInAsync(user); 

标识3.0

await SignInManager.RefreshSignInAsync(user); 
+0

我确实怀疑isPersistent标志与http标题相关,但我仍然不知道为什么会出现http标题。 更改索赔来自其他地方的答案(例如http://stackoverflow.com/questions/24587414/how-to-update-a-claim-in-asp-net-identity),它似乎工作*大多数*的时间,但有时似乎卡住了。 – Mog0

3

而不是

authenticationManager.AuthenticationResponseGrant = 
    new AuthenticationResponseGrant(new ClaimsPrincipal(newIdentity), 
    new AuthenticationProperties { IsPersistent = false }); 

你应该使用

authenticationManager.SignIn(
    new AuthenticationProperties { IsPersistent = false }, 
    new ClaimsPrincipal(newIdentity));