2015-05-27 49 views
4

我正在使用多租户的服务器端应用程序。在这个服务器端,我有一个Backoffice(ASP.NET MVC)和一个后端(WCF)。ASP.NET身份2.0解密Owin cookie

我想解密身份cookie,以便我可以检查它是否有效并使用它在WCF服务中进行身份验证。

更具体的我真的很想知道,如果ASP.NET身份API提供任何形式类似于下面的示例服务(如果我使用窗体身份验证它的工作)提前

FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(tokenValue); 

感谢。

+0

请正确标题错字( “owin” =>“自己”) – kebs

+0

这是正确的,我的意思是欧文饼干不是我自己的Cookie –

+0

好吧,但那么,为什么这个词在问题的任何地方都没有创造出来?标题应该是问题的总结,所以你最好在问题中提供详细的信息(我不知道“Owin cookie”是什么......)。但也许asp家伙知道这是关于什么... – kebs

回答

8

经过大量的研究,我发现了一种在博客中这样做的方法。最终的算法如下所示:

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

注意主要是一样,如果对向auth饼干一边,你只要致电:

HttpContext.Current.User 

如果你有兴趣知道如何该算法的作品,你可以找到它here

+0

明智的答案,允许我通过注入cookie客户端来使用WCF服务中现有的OWIN表单身份验证设置,然后使用此服务器端来允许WCF获取ClaimsIdentity。保存了一天! – Breeno

+1

你可以避免解析字节数组w /'新的TicketSerializer()。反序列化(字节);'。然后直接将Identity传递给'ClaimsPriniciple'。 – NATO24

2

当您配置您的ASP .NET应用程序使用cookie身份验证,您可以提供自己的TicketDataFormat对象与自己的IDataProtector(通常在Startup.Auth.cs):

app.UseCookieAuthentication(new CookieAuthenticationOptions 
{ 
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
    LoginPath = new PathString("/Account/Login"), 
    TicketDataFormat = new TicketDataFormat(...), // Use your own TicketDataFormat 
    Provider = new CookieAuthenticationProvider 
    {  
     OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
      validateInterval: TimeSpan.FromMinutes(30), 
      regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 
    } 
}); 

如果您使用这两个应用程序相同的TicketDataFormat可以得到AuthenticationTicket这样的:

AuthenticationTicket ticket = options.TicketDataFormat.Unprotect(cookie.Value);