2010-07-19 10 views
6

Ho implementato un provider di ruolo personalizzato e configurato nel mio file web.config in questo modo:ASP .NET personalizzato RoleProvider non rispettare cacheRolesInCookie = "true"

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

ho sovrascritto la funzione GetRolesForUser nel mio fornitore di ruoli personalizzato e ne ho fatto un passo avanti e funziona perfettamente. Carica 60 ruoli per l'utente con cui sto testando. Tuttavia, ho notato che GetRolesForUser viene chiamato su ogni richiesta che chiama User.IsInRole. In altre app che ho scritto, lo chiama solo una volta, quindi memorizza il risultato nel cookie. Per qualche motivo, la memorizzazione nella cache non funziona per questa app. Qualche idea sul perché?

risposta

2

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

"La questione di quando mettere in cache (o non cache) in RolePrincipal passato attraverso un certo numero di iterazioni di progettazione, e alla fine abbiamo optato solo su caching per il metodo esposto dal Interfaccia IPrincipal (cioè IsInRole). "

+0

Quindi quale sarebbe un modo migliore per farlo? Voglio che i ruoli si memorizzino nel cookie. –

+0

Trial-and-error e scegliendo con cura quali metodi usare, immagino. – Greg

+5

Il link è rotto. –

1

Lo stesso è vero per me. Si continua a chiamare GetRolesForUser()

+0

Vedere la risposta di Joao, funziona. – Lee

3

Stavo avendo lo stesso problema. Nel mio caso il problema era che stavo impostando Context.User su GenericPrincipal e non su RolePrincipal. Così, invece di:

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

questa fissa per me:

  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 
      } 

I IsValidAuthCookie controlli metodo per nulla e vuota:

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

UPDATE: Dopo l'aggiornamento a MVC5 .NET 4.5 roleManager ha smesso di funzionare (non ha salvato i ruoli nei cookie), quindi ha dovuto salvarlo da solo:

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

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

Posto questo codice su AuthenticationFilter e registrarlo a livello globale. Vedi here.

+0

Ho cercato per ore su questo problema e questo è stato risolto! Grazie mille per aver postato questo! Puoi rispondere a una domanda, qual è il riferimento per il metodo IsValidAuthCookie o quale classe è il codice scritto in cui viene implementato quel metodo? –

+0

Grazie questa risposta ha aiutato molto. Questa è la sola soluzione che risolve il problema della cache che non funziona più in MVC 5 quando si implementa il ruolo di RoleProvider. Lo metto invece nel mio attributo Autorizzazione. – Lee