ASP.NET Identity 2.0 解密 Owin cookie
ASP.NET Identity 2.0 decrypt Owin cookie
我在应用多租户的服务器端应用程序中工作。在这个服务器端我有一个后台(ASP.NET MVC)和一个后端(WCF)。
我想解密身份 cookie,以便我可以检查它是否有效并使用它在 WCF 服务中进行身份验证。
更具体地说,我真的很想知道 ASP.NET Identity API 是否提供任何类型的服务,如以下示例(如果我使用表单身份验证,它会起作用)
FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(tokenValue);
提前致谢。
经过大量研究,我在博客中找到了执行此操作的方法。最终算法如下所示:
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 == "[=10=]" ? ClaimTypes.Name : type;
string value = reader.ReadString();
string valueType = reader.ReadString();
valueType = valueType == "[=10=]" ?
"http://www.w3.org/2001/XMLSchema#string" :
valueType;
string issuer = reader.ReadString();
issuer = issuer == "[=10=]" ? "LOCAL AUTHORITY" : issuer;
string originalIssuer = reader.ReadString();
originalIssuer = originalIssuer == "[=10=]" ?
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;
}
}
}
}
请注意,principal 就像在发送您刚刚调用的身份验证 cookie 的一方:
HttpContext.Current.User
如果您有兴趣了解该算法的工作原理,可以找到它 here
当您将 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);
我在应用多租户的服务器端应用程序中工作。在这个服务器端我有一个后台(ASP.NET MVC)和一个后端(WCF)。
我想解密身份 cookie,以便我可以检查它是否有效并使用它在 WCF 服务中进行身份验证。
更具体地说,我真的很想知道 ASP.NET Identity API 是否提供任何类型的服务,如以下示例(如果我使用表单身份验证,它会起作用)
FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(tokenValue);
提前致谢。
经过大量研究,我在博客中找到了执行此操作的方法。最终算法如下所示:
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 == "[=10=]" ? ClaimTypes.Name : type;
string value = reader.ReadString();
string valueType = reader.ReadString();
valueType = valueType == "[=10=]" ?
"http://www.w3.org/2001/XMLSchema#string" :
valueType;
string issuer = reader.ReadString();
issuer = issuer == "[=10=]" ? "LOCAL AUTHORITY" : issuer;
string originalIssuer = reader.ReadString();
originalIssuer = originalIssuer == "[=10=]" ?
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;
}
}
}
}
请注意,principal 就像在发送您刚刚调用的身份验证 cookie 的一方:
HttpContext.Current.User
如果您有兴趣了解该算法的工作原理,可以找到它 here
当您将 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);