服务器端使用 Owin 身份验证声明缓存 [英] Server side claims caching with Owin Authentication

查看:29
本文介绍了服务器端使用 Owin 身份验证声明缓存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个过去使用 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.

我正在研究 OwinAuthenticationAsp.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...

  1. cookie 保持为 3KB,哦,它有点大.
  2. 在我不知道的 Owin 中启用类似于 IdentityModel 的 SessionCaching 的功能.
  3. 编写我自己的实现来缓存导致 cookie 膨胀的信息,看看我在应用程序启动时配置 Owin 时是否可以连接它.
  4. 我在这一切都做错了,有一种我没有想到的方法,或者我在 Owin 中滥用了某些东西.

  1. The cookie stays as 3KB, oh well it's a little large.
  2. Enable a feature similar to IdentityModel's SessionCaching in Owin that I don't know about.
  3. 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.
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆