我有一个 Owin Identity 应用程序和另一个应用程序在虚拟目录中设置。虚拟应用程序是使用传统的窗体身份验证设置的,并且两个 Web.config 具有相同的<machineKey>
集。我可以使用身份应用程序登录,并可以看到生成的cookie。但是,当我尝试访问虚拟应用程序时,它说我没有经过身份验证。
在标识应用中,我有以下设置:
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))
}
});
在虚拟应用程序中,我已按如下方式设置了授权:
<authorization>
<deny users="?" />
</authorization>
有什么指示可以让虚拟应用程序识别由 Identity 设置的 cookie 吗?
Cookie 包含身份验证票证。对于 cookie 身份验证中间件与表单身份验证,此票证的格式是不同的。无法使 FAM 读取由 Cookie 身份验证中间件创建的 Cookie。也就是说,您可以编写自己的HTTP模块,类似于FAM来读取由cookie身份验证中间件创建的cookie,如下所示。
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 == " " ? ClaimTypes.Name : type;
string value = reader.ReadString();
string valueType = reader.ReadString();
valueType = valueType == " " ?
"http://www.w3.org/2001/XMLSchema#string" :
valueType;
string issuer = reader.ReadString();
issuer = issuer == " " ? "LOCAL AUTHORITY" : issuer;
string originalIssuer = reader.ReadString();
originalIssuer = originalIssuer == " " ?
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() { }
}
有关我在这里所做的事情的解释,请转到我的博客条目。
http://lbadri.wordpress.com/2014/11/23/reading-katana-cookie-authentication-middlewares-cookie-from-formsauthenticationmodule/
它太大了,无法在这里解释。