Серверная сторона утверждает, что кеширование с аутентификацией Owin

У меня есть приложение, которое использовало FormsAuthentication, и некоторое время назад я переключил его на использование IdentityModel from WindowsIdentityFramework, чтобы я мог воспользоваться проверкой на основе утверждений, но было довольно уродливо использовать и воплощать в жизнь. Итак, теперь я смотрю OwinAuthentication.

Я смотрю OwinAuthentication и структуру Asp.Net Identity. Но реализация Asp.Net Identity framework только в настоящее время использует EntityModel, и я использую nHibernate. Поэтому на данный момент я пытаюсь обойти Asp.Net Identity и просто использовать Owin Authentication напрямую. Я, наконец, смог получить рабочий логин, используя подсказки от Как игнорировать макет Identity Framework и просто использовать промежуточное ПО OWIN для получения претензий, которые я ищу? ", но теперь мой cookie с претензиями довольно большой. Когда я использовал IdentityModel, я смог использовать механизм кеширования на стороне сервера, который кэшировал претензии на сервере, а cookie просто держал простой токен для кэшированной информации. Есть ли аналогичная функция в OwinAuthentication, или я должен сам ее реализовать?

Я ожидаю, что я буду на одной из этих лодок...

  1. Файл cookie остается 3KB, ну, это немного большой.
  2. Включить функцию, похожую на IdentityModel SessionCaching в Owin, о которой я не знаю.
  3. Напишите мою собственную реализацию для кэширования информации, вызывающей раздувание куки файлов, и посмотрите, могу ли я подключить его, когда я настраиваю 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),
            });
        }
    }
    

UPDATE Я смог получить желаемый эффект, используя информацию, предоставленную Hongye, и я придумал логику ниже...

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 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);
    }
}

Ответ 1

Связность аутентификации cookie OWIN для cookie не поддерживает кеширование сеанса, как функция. # 2 не является параметром.

# 3 - правильный путь. Как предложил Прабху, вы должны сделать следующее в своем коде:

OnResponseSignIn:

  • Сохранить контекст.Идентичность в кеше с уникальным ключом (GUID)
  • Создайте новый элемент ClaimsIdentity, встроенный с уникальным ключом
  • Заменить context.Identity с новым идентификатором

OnValidateIdentity:

  • Получить уникальное ключевое требование из контекста. Идентификация
  • Получить кешированный идентификатор с помощью уникального ключа
  • контекст вызова .ReplaceIdentity с кэшированным идентификатором

Я собирался предложить вам gzip cookie, но я обнаружил, что OWIN уже сделал это в своем TicketSerializer. Не вариант для вас.

Ответ 2

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

Ответ 3

Вы можете реализовать IAuthenticationSessionStore для хранения файлов cookie в базе данных.

Здесь пример сохранения cookie в redis.

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
SessionStore = new RedisSessionStore(new TicketDataFormat(dataProtector)),
LoginPath = new PathString("/Auth/LogOn"),
LogoutPath = new PathString("/Auth/LogOut"),

});

Посмотрите полный пример здесь