Using ASP.Net Identity 2 cookie in form validation
I have an Owin Identity app and another app configured in a virtual directory. The virtual application is configured using traditional forms authentication and both Web.configs have the same set <machineKey>
. I can login with Identity app and see the received cookie. However, when I try to access the virtual app, it says that I am not authenticated.
In 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 configured like this:
<authorization>
<deny users="?" />
</authorization>
Any pointers for the virtual app to recognize the cookie set using Identity?
source to share
The cookie contains an authentication ticket. The format of this ticket is different for cookie middleware authentication and forms authentication. There is no way to get FAM to read a cookie created by the cookie authentication middleware. However, you can write your own FAM-like HTTP module to read the cookie generated by the cookie authentication middleware, for example.
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 an explanation of what I'm doing here, go to my blog post.
It's too hard to explain here.
source to share