Cache des revendications côté serveur avec authentification Owin

j'ai une application qui utilisait FormsAuthentication , et il y a quelque temps je l'ai commuté pour utiliser le IdentityModel de WindowsIdentityFramework afin que je puisse bénéficier de l'authentification basée sur les revendications, mais il était plutôt laid à utiliser et à mettre en œuvre. Donc maintenant je regarde OwinAuthentication .

je regarde OwinAuthentication et le cadre Asp.Net Identity . Mais la seule implémentation du framework Asp.Net Identity actuellement utilise EntityModel et j'utilise nHibernate . Donc, pour maintenant je cherche à court-circuiter Asp.Net Identity et juste utiliser le Owin Authentication directement. J'ai finalement pu obtenir un login de travail en utilisant les conseils de " Comment puis-je ignorer la magie du cadre D'identité et juste utiliser L'middleware OWIN auth pour obtenir les revendications que je cherche? ", mais maintenant mon cookie contenant les revendications est assez grand. Lorsque j'ai utilisé le IdentityModel j'ai pu utiliser un mécanisme de mise en cache côté serveur qui cache les revendications sur le serveur et le cookie juste tenu un simple jeton pour les informations mises en cache. Y a-t-il une caractéristique similaire dans OwinAuthentication , ou devrais-je l'implémenter moi-même?

Je m'attends à être dans l'un de ces bateaux...

  1. le cookie reste comme 3KB, Oh bien il est un peu grand.
  2. permet une fonctionnalité similaire à celle de IdentityModel dans Owin que je ne connais pas.
  3. écrire ma propre implémentation pour mettre en cache le les informations qui font gonfler le cookie et voir si je peux le connecter lorsque je configure Owin au démarrage de l'application.
  4. je fais tout de Travers et il y a une approche à laquelle je n'ai pas pensé ou j'utilise quelque chose dans 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),
            });
        }
    }
    

mise à JOUR J'ai pu obtenir l'effet désiré en utilisant les informations fournies par Hongye et j'ai trouvé la logique ci-dessous...

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);
    }
}
29
demandé sur Community 2013-10-05 03:51:58

3 réponses

OWIN cookie authentication middleware ne supporte pas encore la fonctionnalité de mise en cache de session. #2 n'est pas une option.

#3 est la bonne voie à suivre. Comme Prabu l'a suggéré, vous devriez faire ce qui suit dans votre code:

OnResponseSignIn:

  • Enregistrer contexte.L'identité dans le cache avec une clé unique(GUID)
  • Créer un nouveau ClaimsIdentity intégré avec la clé unique
  • remplacer cadre.Identité avec la nouvelle identité

OnValidateIdentity:

  • Obtenir la clé unique de demande de contexte.Identité
  • Obtenir la mise en cache de l'identité par la clé unique
  • Appel le contexte.Remplaçéidentité avec l'identité mise en cache

j'allais vous suggérer de gzip le cookie, mais J'ai trouvé QU'OWIN l'avait déjà fait dans son TicketSerializer. Pas une option pour vous.

14
répondu Hongye Sun 2013-10-07 18:05:36
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. 
    }
}
8
répondu Praburaj 2016-02-22 10:52:31

vous pouvez implémenter IAuthenticationSessionStore pour stocker les cookies dans la base de données.

voici un exemple pour stocker un cookie dans redis.

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

});

découvrez toute l'exemple ici

1
répondu Alex Nguyen 2016-08-03 06:20:11