Server side claims Owin authentication caching

I have an application that used FormsAuthentication , and some time ago I switched it to using IdentityModel from WindowsIdentityFramework so that I could use claims-based validation, but it was pretty ugly to use and implement. So now I'm watching OwinAuthentication .

I look at OwinAuthentication and the Asp.Net Identity framework. But the Asp.Net Identity framework implementation only currently uses EntityModel and I am using nHibernate . So for now, I'm trying to get around Asp.Net Identity and just use Owin Authentication directly. I was finally able to get a working login using the hints from How to ignore the Identity Framework layout and just use the OWIN middleware to get the claims I'm looking for? "but now my claims cookie is pretty big. When I used IdentityModel , I was able to use a server-side caching mechanism that cached claims on the server, and the cookie just kept a simple token for cached information. Is there a similar feature in OwinAuthentication , or am I Should I implement it myself?

I expect that I will be on one of these boats ...

  1. The cookie remains 3KB, well, it's a bit big.
  2. Enable a feature similar to IdentityModel SessionCaching in Owin that I don't know about.
  3. Write my own implementation for caching information that causes bloating cookies, and see if I can connect it when I configure Owin when the application starts.
  4. I'm doing it all wrong, and there is an approach that I have not thought about, or something is wrong 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 provided by Hongye, and I came up with the logic below ...

 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 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); } } 
+29
authentication claims-based-identity owin
04 Oct '13 at 23:51
source share
3 answers

OWIN cookie authentication connectivity for cookies does not support session caching as a function. # 2 is not an option.

# 3 is the right way. As Prabhu suggested, you should do the following in your code:

OnResponseSignIn:

  • Keep context. Identity in cache with unique key (GUID)
  • Create a new ClaimsIdentity element embedded with a unique key
  • Replace context.Identity with a new identifier

OnValidateIdentity:

  • Get a unique key requirement from the context. Identification
  • Get a cached identifier using a unique key
  • call context .ReplaceIdentity with cached identifier

I was going to offer you a gzip cookie, but I found that OWIN already did this in my TicketSerializer. Not an option for you.

+14
07 Oct '13 at 18:05
source share
 Provider = new CookieAuthenticationProvider() { OnResponseSignIn = async context => { // This is the last chance before the ClaimsIdentity get serialized into a cookie. // You can modify the ClaimsIdentity here and create the mapping here. // This event is invoked one time on sign in. }, OnValidateIdentity = async context => { // This method gets invoked for every request after the cookie is converted // into a ClaimsIdentity. Here you can look up your claims from the mapping table. } } 
+8
Oct 05 '13 at 2:16
source share

You can implement IAuthenticationSessionStore to store cookies in the database.

Here is an example of saving a cookie in redis.

 app.UseCookieAuthentication(new CookieAuthenticationOptions { AuthenticationType = CookieAuthenticationDefaults.AuthenticationType, SessionStore = new RedisSessionStore(new TicketDataFormat(dataProtector)), LoginPath = new PathString("/Auth/LogOn"), LogoutPath = new PathString("/Auth/LogOut"), }); 

See the full example here.

+1
Aug 03 '16 at 6:20
source share



All Articles