服务器端声明使用 Owin 身份验证进行缓存



我有一个曾经使用FormsAuthentication的应用程序,不久前我将其切换为使用WindowsIdentityFrameworkIdentityModel,以便我可以从基于声明的身份验证中受益,但是使用和实现起来相当丑陋。所以现在我正在看OwinAuthentication.

我正在研究OwinAuthenticationAsp.Net Identity框架。但是Asp.Net Identity框架目前唯一的实现使用EntityModel而我正在使用nHibernate。所以现在我想尝试绕过Asp.Net Identity,直接使用Owin Authentication。我终于能够使用"我如何忽略身份框架魔法,只使用 OWIN 身份验证中间件来获取我寻求的声明?"中的提示获得工作登录,但现在我的 cookie 保存声明相当大。当我使用IdentityModel时,我能够使用服务器端缓存机制,该机制在服务器上缓存声明,并且cookie只是保存缓存信息的简单令牌。OwinAuthentication 中是否有类似的功能,还是我必须自己实现它?

我希望我会在其中一条船上...

  1. 饼干保持为3KB,哦,它有点大。
  2. 启用类似于我不知道的Owin IdentityModel 的会话缓存的功能。
  3. 编写我自己的实现来缓存导致 cookie 膨胀的信息,看看当我在应用程序启动时配置Owin时是否可以挂接它。
  4. 我做错了这一切,有一种我没有想到的方法,或者我在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);
    }
}

OWIN cookie 身份验证中间件尚不支持会话缓存之类的功能。 #2 不是一个选项。

#3 是正确的方法。正如 Prabu 所建议的,您应该在代码中执行以下操作:

OnResponseSignIn:

  • 保存上下文。缓存中具有唯一键 (GUID( 的标识
  • 创建嵌入唯一键的新声明标识
  • 替换上下文。使用新身份标识

OnValidateIdentity:

  • 从上下文中获取唯一键声明。身份
  • 通过唯一键获取缓存的标识
  • 调用上下文。将标识替换为缓存的标识

我打算建议你压缩cookie,但我发现OWIN已经在其TicketSerializer中这样做了。不适合您。

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. 
    }
}

您可以实现 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"),
});

在此处查看完整示例

相关内容

  • 没有找到相关文章