我有一个曾经使用FormsAuthentication
的应用程序,不久之前我将其切换为使用IdentityModel
中的WindowsIdentityFramework
,以便我可以从基于声明的身份验证中受益,但它使用和实施相当丑陋。所以现在我看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
中是否有类似的功能,或者我必须自己实现它?
我希望我会参加其中一艘船......
IdentityModel
中启用类似于Owin
的SessionCaching的功能,我不知道。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);
}
}
答案 0 :(得分:15)
OWIN cookie身份验证中间件不支持类似功能的会话缓存。 #2不是一个选项。
#3是正确的方法。正如Prabu建议的那样,您应该在代码中执行以下操作:
OnResponseSignIn:
OnValidateIdentity:
我打算建议你gzip cookie,但我发现OWIN已经在它的TicketSerializer中做到了。不适合你。
答案 1 :(得分:8)
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.
}
}
答案 2 :(得分:1)
您可以实施IAuthenticationSessionStore将Cookie存储到数据库中。
以下用于在redis中存储Cookie的示例。
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SessionStore = new RedisSessionStore(new TicketDataFormat(dataProtector)),
LoginPath = new PathString("/Auth/LogOn"),
LogoutPath = new PathString("/Auth/LogOut"),
});
查看完整示例at here