2010-07-19 10 views
6

he implementado un proveedor de papel personalizado y configurado en mi archivo web.config como esto:ASP .NET personalizado RoleProvider no respetar cacheRolesInCookie = "true"

<roleManager enabled="true" defaultProvider="TDRoleProvider" cacheRolesInCookie="true"> 
    <providers> 
    <clear/> 
    <add name="TDRoleProvider" type="TDRoleProvider"/> 
    </providers> 
</roleManager> 

hemos anulado la función GetRolesForUser en mi proveedor de roles personalizado, y entré en escena, y funciona perfectamente: carga 60 funciones para el usuario con el que estoy probando. Sin embargo, me he dado cuenta de que se llama a GetRolesForUser en cada solicitud que llama a User.IsInRole. En otras aplicaciones que he escrito, solo lo llama una vez, luego guarda el resultado en la cookie. Por algún motivo, el almacenamiento en caché no funciona para esta aplicación. ¿Alguna idea de por qué?

Respuesta

2

http://connect.microsoft.com/VisualStudio/feedback/details/104688/rolemanager-cacherolesincookie-option-does-not-work

"La cuestión de cuándo debe almacenar en caché (o no caché) en RolePrincipal pasó por una serie de iteraciones de diseño, y finalmente nos quedamos sólo en caché para el método expuesto por la Interfaz IPrincipal (es decir, IsInRole). "

+0

Entonces, ¿cuál sería una mejor manera de hacer esto? Quiero que los roles guarden en la cookie. –

+0

Prueba y error y elegir cuidadosamente qué métodos usar, supongo. – Greg

+5

El enlace está roto. –

1

Lo mismo es cierto para mí. Se sigue llamando GetRolesForUser()

+0

Ver la respuesta de Joao, funciona. – Lee

3

Estaba teniendo el mismo problema. En mi caso, el problema era que estaba configurando Context.User en GenericPrincipal y no en RolePrincipal. Así que en lugar de:

this.Context.User = new GenericPrincipal(customIdentity, roles); 

que esto esté arreglado para mí:

  HttpCookie roleCookie = this.Context.Request.Cookies[Roles.CookieName]; 
      if (IsValidAuthCookie(roleCookie)) 
      { 
       this.Context.User = new RolePrincipal(customIdentity, roleCookie.Value); 
      } 
      else 
      { 
       this.Context.User = new RolePrincipal(customIdentity); 
       var x = this.Context.User.IsInRole("Visitor"); // do this to cache the results in the cookie 
      } 

Los IsValidAuthCookie método comprueba para nulo y vacío:

private static bool IsValidAuthCookie(HttpCookie authCookie) 
    { 
     return authCookie != null && !String.IsNullOrEmpty(authCookie.Value); 
    } 

ACTUALIZACIÓN: Después de actualizar a MVC5 .NET 4.5 roleManager dejó de funcionar (no guardaba roles en la cookie) así que tuve que guardarlo yo mismo:

 HttpCookie roleCookie = filterContext.HttpContext.Request.Cookies[Roles.CookieName]; 
     if (IsValidAuthCookie(roleCookie)) 
     { 
      filterContext.Principal = new RolePrincipal(customIdentity, roleCookie.Value); 
      RolePrincipal rp = (RolePrincipal)filterContext.Principal; 
      if (!rp.IsRoleListCached) // check if roles loaded properly (if loads old cookie from another user for example, roles won't be loaded/cached). 
      { 
       // roles not loaded. Delete and save new 
       Roles.DeleteCookie(); 
       rp.IsInRole("Visitor"); // load Roles 
       SaveRoleCookie(rp, filterContext); 
      } 

     } 
     else 
     { 
      filterContext.Principal = new RolePrincipal(customIdentity); 
      filterContext.Principal.IsInRole("Visitor"); // do this to cache the results in the cookie. 
      SaveRoleCookie(filterContext.Principal as RolePrincipal, filterContext); 
     } 

Guardar la roleCookie

private void SaveRoleCookie(RolePrincipal rp, AuthenticationContext filterContext) 
    { 
     string s = rp.ToEncryptedTicket(); 
     const int MAX_COOKIE_LENGTH = 4096; 
     if (string.IsNullOrEmpty(s) || s.Length > MAX_COOKIE_LENGTH) 
     { 
      Roles.DeleteCookie(); 
     } 
     else 
     { 
      HttpCookie cookie = new HttpCookie(Roles.CookieName, s); 
      cookie.HttpOnly = true; 
      cookie.Path = Roles.CookiePath; 
      cookie.Domain = Roles.Domain; 
      if (Roles.CreatePersistentCookie) 
       cookie.Expires = rp.ExpireDate; 
      cookie.Secure = Roles.CookieRequireSSL; 
      filterContext.HttpContext.Response.Cookies.Add(cookie); 
     } 
    } 

Coloque este código en AuthenticationFilter y registrarlo a nivel mundial. Ver here.

+0

He estado buscando horas sobre este tema y esto lo solucionó! ¡Muchas gracias por publicar esto! ¿Puedes responder una pregunta, cuál es la referencia para el método IsValidAuthCookie o en qué clase está escrito el código que implementa ese método? –

+0

Gracias esta respuesta ayudó mucho. Esta es la única solución que aborda el almacenamiento en caché que ya no funciona en MVC 5 cuando implementa RownProvider. Lo pongo en mi propio atributo Autorización en su lugar. – Lee

Cuestiones relacionadas