Using ASP.Net Identity 2 cookie in forms authentic

2019-02-19 01:29发布

问题:

I have an Owin Identity application and another application set up in a virtual directory. The virtual app is set up using traditional forms authentication, and both Web.configs have the same <machineKey> set. I can login using the Identity app, and can see the resulting cookie. However, when I try to access the virtual app it says I am not authenticated.

In the Identity app, I have the following setup:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
  AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
  LoginPath = new PathString("/login.aspx"),
  Provider = new CookieAuthenticationProvider
  {
    // Enables the application to validate the security stamp when the user logs in.
    // This is a security feature which is used when you change a password or add an external login to your account.  
    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
      validateInterval: TimeSpan.FromMinutes(30),
      regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
  }
});

And in the virtual app, I have authorization set up as follows:

<authorization>
      <deny users="?" />
</authorization>

Any pointers to get the virtual app to recognize the cookie set by Identity?

回答1:

The cookie contains authentication ticket. The format of this ticket is different for cookie authentication middleware vs forms authentication. It is not possible to make FAM read the cookie created by the cookie authentication middleware. That said, you can write your own HTTP module, similar to FAM to read the cookie created by the cookie authentication middleware, like this.

public class MyHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        context.AuthenticateRequest += OnApplicationAuthenticateRequest;
    }
    private static void OnApplicationAuthenticateRequest(object sender, EventArgs e)
    {
        var request = HttpContext.Current.Request;
        var cookie = request.Cookies.Get(".AspNet.ApplicationCookie");
        var ticket = cookie.Value;
        ticket = ticket.Replace('-', '+').Replace('_', '/');

        var padding = 3 - ((ticket.Length + 3) % 4);
        if (padding != 0)
            ticket = ticket + new string('=', padding);

        var bytes = Convert.FromBase64String(ticket);

        bytes = System.Web.Security.MachineKey.Unprotect(bytes,
            "Microsoft.Owin.Security.Cookies.CookieAuthenticationMiddleware",
                "ApplicationCookie", "v1");

        using (var memory = new MemoryStream(bytes))
        {
            using (var compression = new GZipStream(memory, 
                                                CompressionMode.Decompress))
            {
                using (var reader = new BinaryReader(compression))
                {
                    reader.ReadInt32();
                    string authenticationType = reader.ReadString();
                    reader.ReadString();
                    reader.ReadString();

                    int count = reader.ReadInt32();

                    var claims = new Claim[count];
                    for (int index = 0; index != count; ++index)
                    {
                        string type = reader.ReadString();
                        type = type == "\0" ? ClaimTypes.Name : type;

                        string value = reader.ReadString();

                        string valueType = reader.ReadString();
                        valueType = valueType == "\0" ? 
                                       "http://www.w3.org/2001/XMLSchema#string" : 
                                         valueType;

                        string issuer = reader.ReadString();
                        issuer = issuer == "\0" ? "LOCAL AUTHORITY" : issuer;

                        string originalIssuer = reader.ReadString();
                        originalIssuer = originalIssuer == "\0" ? 
                                                     issuer : originalIssuer;

                        claims[index] = new Claim(type, value, 
                                               valueType, issuer, originalIssuer);
                    }

                    var identity = new ClaimsIdentity(claims, authenticationType, 
                                                  ClaimTypes.Name, ClaimTypes.Role);

                    var principal = new ClaimsPrincipal(identity);

                    System.Threading.Thread.CurrentPrincipal = principal;
                    HttpContext.Current.User = principal;
                }
            }
        }
    }


    public void Dispose() { }
}

For the explanation of what I do here, please go to my blog entry.

http://lbadri.wordpress.com/2014/11/23/reading-katana-cookie-authentication-middlewares-cookie-from-formsauthenticationmodule/

It is too big to explain here.