【发布时间】:2013-10-12 02:43:11
【问题描述】:
我有一个曾经使用FormsAuthentication 的应用程序,不久前我将它从WindowsIdentityFramework 切换为使用IdentityModel,这样我就可以从基于声明的身份验证中受益,但是使用起来相当难看,而且实施。所以现在我在看OwinAuthentication。
我正在研究OwinAuthentication 和Asp.Net Identity 框架。但是Asp.Net Identity 框架目前唯一的实现使用EntityModel,而我正在使用nHibernate。所以现在我想尝试绕过Asp.Net Identity,直接使用Owin Authentication。我终于能够使用来自“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), }); } }
更新 使用宏业提供的信息,我能够得到想要的效果,我想出了以下逻辑......
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);
}
}
【问题讨论】:
-
为什么不使用 ASP.NET 标识的自定义实现? NuGet 上已经有实现。
-
我处理这个的时候没有,你指的是什么?
-
Nhibernate.AspNet.Identity 和 AspNet.Identity.NHibernate(我使用 SharpArchitecture 和 FluentNHibernate 创建了这个。不过它是一个预发布版本)
-
CookieAuthenticationOptions 对象上有一个名为“SessionStore”的字段,它被描述为“一个可选的容器,用于存储跨请求的身份。使用时,只会向客户端发送会话标识符。这可以用来缓解非常大的身份的潜在问题。”这似乎是你想要做的。不幸的是,我找不到任何关于如何实际创建这些 SessionStores 的参考。
-
声明是
System.Security.Claims.Claim?GetUserId扩展的代码?
标签: asp.net authentication claims-based-identity owin