Search code examples
asp.netasp.net-mvcwcfcookiesasp.net-identity

ASP.NET Identity 2.0 decrypt Owin cookie


I'm working in a server-side application where I'm applying multi tenancy. In this server side I have a Backoffice (ASP.NET MVC) and a BackEnd (WCF).

I want to decrypt Identity cookie so that I can check that it is valid and use it to auth in WCF Services.

To be more specific I really want to know if ASP.NET Identity API provides any kind of service like the following example (it would work if I was using forms Authentication)

FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(tokenValue);

Thanks in advance.


Solution

  • After a lot of research I found a way to do this in a blog. The final algorithm looks like the following:

          private bool BackOfficeUserAuthorized(string ticket)
          {
            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);
    
                        return principal.Identity.IsAuthenticated;
                    }
                }
            }
        }
    

    Be aware that principal is like if on the side that sends the auth cookie you just call:

    HttpContext.Current.User
    

    If you are interested in know how the algorithm works you can find it here