2010-07-19 32 views
6

我已經實現了一個自定義角色提供商,並在我的web.config文件中這樣配置的:ASP .NET自定義RoleProvider不尊重cacheRolesInCookie =「真」

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

我已經覆蓋了GetRolesForUser功能在我的自定義角色提供者中,並且我已經進入了它,並且它工作得很好 - 爲我正在測試的用戶加載60個角色。但是,我注意到每個調用User.IsInRole的請求都會調用GetRolesForUser。在我編寫的其他應用程序中,它只調用一次,然後將結果緩存到Cookie中。出於某種原因,緩存不適用於此應用程序。任何想法爲什麼?

回答

2

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

「的時候緩存(或不緩存)在RolePrincipal通過一些設計迭代的去了,我們終於上只緩存解決由暴露的方法的問題IPrincipal接口(即IsInRole)。「

+0

那麼最好的方法是做什麼?我想要角色緩存在cookie中。 – 2011-06-07 20:56:49

+0

試試錯誤並仔細選擇使用哪種方法,我想。 – Greg 2011-06-07 21:02:01

+5

鏈接已損壞。 – 2012-08-31 14:36:13

1

對我來說也是如此。它不斷給你打電話GetRolesForUser()

+0

查看Joao的答案,它的工作原理。 – Lee 2017-05-25 12:17:31

3

我遇到了同樣的問題。在我的情況下,問題是我將Context.User設置爲GenericPrincipal而不是RolePrincipal。因此,而不是:

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

這個固定的對我來說:

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

UPDATE:

  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 
      } 

IsValidAuthCookie法空,空檢查升級到MVC5 .NET 4.5后角色管理器停止工作(不保存cookie中的角色),因此必須自己保存它:

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

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

將此代碼上AuthenticationFilter和全球註冊。見here

+0

我一直在這個問題上尋找幾個小時,並修復它!非常感謝你張貼這個!你能回答一個問題:方法IsValidAuthCookie的引用是什麼,或者寫入的代碼是用什麼類實現的? – 2015-04-01 20:02:10

+0

謝謝這個答案很多。這是他唯一的解決方案,當你實現你的RoleProvider時,解決了緩存不再在MVC 5中工作。我把它放在我自己的授權屬性中。 – Lee 2017-05-25 12:16:58

相關問題