我在看OwinAuthentication和Asp.Net身份框架。但是Asp.Net Identity框架的唯一实现使用EntityModel和我使用nHibernate。所以,现在我正在寻求尝试绕过Asp.Net身份,只是直接使用Owin身份验证。我终于能够得到一个工作登录使用从“How do I ignore the Identity Framework magic and just use the OWIN auth middleware to get the claims I seek?”的提示,但现在我的cookie持有索赔是相当大。当我使用IdentityModel时,我能够使用服务器端缓存机制缓存在服务器上的声明,cookie只是为缓存的信息保存一个简单的令牌。在OwinAuthentication中有类似的功能,还是我自己实现它?
我希望我会在这些船之一…
> Cookie保持为3KB,哦,它有点大。
>启用类似于Owin中IdentityModel的SessionCaching的功能,我不知道。
>编写自己的实现来缓存导致cookie膨胀的信息,看看我是否可以在应用程序启动时配置Owin时挂断它。
>我做这个错误,有一种方法,我没有想到或我在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),}); } }
更新
我能够使用Hongye提供的信息获得所需的效果,我想出了以下逻辑…
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); } }
解决方法
#3是正确的方式。正如Prabu建议的,你应该在你的代码中:
OnResponseSignIn:
>使用唯一键(GUID)在缓存中保存context.Identity
>使用唯一键创建一个新的ClaimsIdentity
>用新标识替换context.Identity
OnValidateIdentity:
>从context.Identity获取唯一的键声明
>通过唯一键获取缓存的标识
>使用缓存的标识调用context.ReplaceIdentity
我会建议你gzip的cookie,但我发现OWIN已经在它的TicketSerializer。不是你的选择。