Search code examples
c#asp.netasp.net-mvcasp.net-identity

ASP.NET Identity: Not updating cookie after modifying claims


I'm having issues with updating claims on ASP.Net Identity 2.2.1 in .Net 4.6.2 / MVC5. After updating a claim it will normally send an updated cookie to the browser and everything works fine but sometimes no set cookie header is sent to the browser.

I've not been able to identify any pattern as to when it happens other than when it is failing, the server is sending a

Persistent-Auth: true

http header value for every response in the session. I don't know what causes this header value to get set and it sometimes appears mid-session and once it starts sending it, it will be sent for the rest of the session and trying to update the claims will never work again for that session.

As far as I can see, I have hard-coded the isPersistent parameter to be false in every call into ASP.Net identity and I can't see anything else that could be related to this header.

The code I'm using for updating claims is

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 });
}

This is being called from an MVC action method.

Does anyone have any suggestions what might be going wrong or even just a starting point of where to look? I don't know what causes that persistent-auth header but it looks to be related to the problem; whether it is the cause or a symptom of the problem, I don't know.

I'm using ASP.Net Identity 2.2.1 with .Net 4.6.2. I'm running on Windows Server 2012R2 and the problem seems to occur with IE11, Chrome and Firefox. I'm using Fiddler 4.6.3 to view the http headers / responses.

Update: I have noticed that it seems to go wrong only when Windows authentication is enabled. My server has a setting that allows username/password, windows auth or both (user can choose to sign in as a different user using username/password). When windows auth is used, I initially authenticate the user using windows and then set a cookie, which I then use for all future requests in the session. If windows auth is disabled, updating the claims like this always works. If windows auth is enabled, updating the claims usually works.


Solution

  • I found the problem. It was using the wrong identity when it tried to update the claims. In my scenario there were two identity objects, one for windows authentication and one for cookie authentication. In most cases HttpContext.Current.User.Identity gets the cookie authentication object (which is the one with the claims) but occasionally it was giving me the windows authentication object, so when I tried to update the claims on that, it didn't do anything.

    The problem was solved by replacing

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

    with

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

    It now seems to work solidly without needing to sign out / back in again.

    I guess the Persistent-Auth: true http header was being sent when OWin considered the Windows auth to be the primary identity so that is why its presence correlated with the inability to update claims.