Persisting claims across requests

Good question. Even made me do a little experiment.

This line:

AuthenticationManager.SignIn(
          new AuthenticationProperties { IsPersistent = true }, identity );

Does not set a cookie. Only sets Identity object for the later callback.

Cookie is only set when the control is passed to middleware and some OWIN internal method called Response.OnSendingHeaders.

So your code is just adding claim2 on the identity object that is stored in memory for later user. In theory you can even set claim1 after you have done the AuthenticationManager.SignIn. And it will be persisted in the cookie anyway.

If you try to add a cliam like this in a controller:

    public ActionResult AddNonPersistedClaim()
    {
        var identity = (ClaimsIdentity)ClaimsPrincipal.Current.Identity;
        identity.AddClaim(new Claim("Hello", "World"));

        return RedirectToAction("SomeAction");
    }

This claim won't be set in the cookie and you will not see it in the next request.

If you'd like to have a deeper look how it all works, check out the source code of Katana Project, look on Microsoft.Owin.Security and Microsoft.Owin.Security.Cookies projects. Along with AuthenticationManager in Microsoft.Owin.Net45 project.

Update

To answer your Edit 1 - IdentityUserClaim is indeed persisted into the database and this is the way you can assign persisted claims to the user. You add these on the user through UserManager

await userManager.AddClaimAsync(userId, new Claim("ClaimType", "ClaimValue"));

This creates records in your database table that represents IdentityUserClaim. When next time user is logged in, these claims are read from the database and added to the identity and are available on ClaimsIdentity.Current via property .Claims or by method .HasClaim().

IdentityUserClaim does not do anything else - just way to serialise Claim object into the database. You don't usually access these directly, unless you want to go "bare knuckles" and write to that table yourself, outside of UserManager.

To put it another way - Identity does not set the cookie. OWIN creates the cookie. Have a look on this piece of code:

    public async Task SignInAsync(IAuthenticationManager authenticationManager, ApplicationUser applicationUser, bool isPersistent)
    {
        authenticationManager.SignOut(
            DefaultAuthenticationTypes.ExternalCookie,
            DefaultAuthenticationTypes.ApplicationCookie,
            DefaultAuthenticationTypes.TwoFactorCookie,
            DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie,
            DefaultAuthenticationTypes.ExternalBearer);

        var identity = await this.CreateIdentityAsync(applicationUser, DefaultAuthenticationTypes.ApplicationCookie);
        identity.AddClaim(new Claim(ClaimTypes.Email, applicationUser.Email));

        authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
    }

Here Authentication manager is part of OWIN. Identity is part of System.Security.Claims. All that belongs to Identity project is CreateIdentityAsync method - that is basically converts user from the database into ClaimsIdentity with all the persisted roles and claims.

To answer your Edit 2: You are correct, AspNet Identity is not part of Katana project, but Identity uses OWIN (part of Katana) for cookie handling and authorisation. Identity project mostly deals with user/roles/claims persistence and user management, like locking-out, user creation, sending emails with password resetting, 2FA, etc.

What was a surprise for me is that ClaimsPrincipal along with ClaimsIdentity and Claim are part of .Net framework that is available outside of OWIN or Identity. These are used not only in Asp.Net, but in Windows applications. Good thing that .Net now has open-source and you can browse through all these - gives you a better understanding how it all works together. Also if you are doing unit-testing, it is invaluable to know the internals, so you can stub-out all the functionality without using mocks.