I have an application that used to use FormsAuthentication
, and a while ago I switched it to use the IdentityModel
from WindowsIdentityFramework
so that I could benefit from claims based authentication, but it was rather ugly to use and implement. So now I'm looking at OwinAuthentication
.
I'm looking at OwinAuthentication
and the Asp.Net Identity
framework. But the Asp.Net Identity
framework's only implementation at the moment uses EntityModel
and I'm using nHibernate
. So for now I'm looking to try bypassing Asp.Net Identity
and just use the Owin Authentication
directly. I was finally able to get a working login using the tips from "How do I ignore the Identity Framework magic and just use the OWIN auth middleware to get the claims I seek?", but now my cookie holding the claims is rather large. When I used the IdentityModel
I was able to use a server side caching mechanism that cached the claims on the server and the cookie just held a simple token for the cached information. Is there a similar feature in OwinAuthentication
, or would I have to implement it myself?
I expect I'm going to be in one of these boats...
- The cookie stays as 3KB, oh well it's a little large.
- Enable a feature similar to
IdentityModel
's SessionCaching inOwin
that I don't know about. - Write my own implementation to cache the information causing the cookie to bloat and see if I can hook it up when I configure
Owin
at application startup. I'm doing this all wrong and there's an approach I've not thought of or I'm misusing something in
Owin
.public class OwinConfiguration { public void Configuration(IAppBuilder app) { app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = "Application", AuthenticationMode = AuthenticationMode.Active, CookieHttpOnly = true, CookieName = "Application", ExpireTimeSpan = TimeSpan.FromMinutes(30), LoginPath = "/Login", LogoutPath = "/Logout", ReturnUrlParameter="ReturnUrl", SlidingExpiration = true, Provider = new CookieAuthenticationProvider() { OnValidateIdentity = async context => { //handle custom caching here?? } } //CookieName = CookieAuthenticationDefaults.CookiePrefix + ExternalAuthentication.ExternalCookieName, //ExpireTimeSpan = TimeSpan.FromMinutes(5), }); } }
UPDATE I was able to get the desired effect using the information Hongye provided and I came up with the below logic...
Provider = new CookieAuthenticationProvider()
{
OnValidateIdentity = async context =>
{
var userId = context.Identity.GetUserId(); //Just a simple extension method to get the ID using identity.FindFirst(x => x.Type == ClaimTypes.NameIdentifier) and account for possible NULLs
if (userId == null) return;
var cacheKey = "MyApplication_Claim_Roles_" + userId.ToString();
var cachedClaims = System.Web.HttpContext.Current.Cache[cacheKey] as IEnumerable<Claim>;
if (cachedClaims == null)
{
var securityService = DependencyResolver.Current.GetService<ISecurityService>(); //My own service to get the user's roles from the database
cachedClaims = securityService.GetRoles(context.Identity.Name).Select(role => new Claim(ClaimTypes.Role, role.RoleName));
System.Web.HttpContext.Current.Cache[cacheKey] = cachedClaims;
}
context.Identity.AddClaims(cachedClaims);
}
}
See Question&Answers more detail:os