服务器端使用 Owin 身份验证声明缓存 [英] Server side claims caching with Owin Authentication
问题描述
我有一个过去使用 FormsAuthentication
的应用程序,不久前我将其切换为使用 WindowsIdentityFramework
中的 IdentityModel
,以便我可以从基于声明的身份验证中受益,但使用和实施起来相当难看.所以现在我在看 OwinAuthentication
.
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
.
我正在研究 OwinAuthentication
和 Asp.Net Identity
框架.但是 Asp.Net Identity
框架目前唯一的实现是使用 EntityModel
而我使用的是 nHibernate
.所以现在我想尝试绕过 Asp.Net Identity
并直接使用 Owin Authentication
.我终于能够使用如何忽略身份框架魔法而只使用 OWIN 身份验证中间件来获取我寻求的声明?",但现在我的 cookie 持有索赔额比较大.当我使用 IdentityModel
时,我能够使用服务器端缓存机制来缓存服务器上的声明,而 cookie 只为缓存的信息保存一个简单的令牌.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...
- cookie 保持为 3KB,哦,它有点大.
- 在我不知道的
Owin
中启用类似于IdentityModel
的 SessionCaching 的功能. - 编写我自己的实现来缓存导致 cookie 膨胀的信息,看看我在应用程序启动时配置
Owin
时是否可以连接它. 我在这一切都做错了,有一种我没有想到的方法,或者我在
Owin
中滥用了某些东西.
- 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);
}
}
推荐答案
OWIN cookie 身份验证中间件尚不支持类似功能的会话缓存.#2 不是选项.
OWIN cookie authentication middleware doesn't support session caching like feature yet. #2 is not an options.
#3 是正确的方法.正如 Prabu 建议的那样,您应该在代码中执行以下操作:
#3 is the right way to go. As Prabu suggested, you should do following in your code:
OnResponseSignIn:
OnResponseSignIn:
- 使用唯一键 (GUID) 将 context.Identity 保存在缓存中
- 创建一个嵌入唯一键的新 ClaimsIdentity
- 用新身份替换 context.Identity
OnValidateIdentity:
OnValidateIdentity:
- 从 context.Identity 中获取唯一键声明
- 通过唯一键获取缓存的身份
- 使用缓存的身份调用 context.ReplaceIdentity
我打算建议您对 cookie 进行 gzip,但我发现 OWIN 已经在它的 TicketSerializer 中这样做了.不适合您.
I was going to suggest you to gzip the cookie, but I found that OWIN already did that in its TicketSerializer. Not an option for you.
这篇关于服务器端使用 Owin 身份验证声明缓存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!