2010-07-19 24 views
6

Tôi đã thực hiện một nhà cung cấp vai trò tùy chỉnh, và cấu hình nó trong tập tin web.config của tôi như thế này:ASP NET Tuỳ chỉnh RoleProvider không tôn trọng cacheRolesInCookie = "true"

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

Tôi đã ghi đè các chức năng GetRolesForUser trong nhà cung cấp vai trò tùy chỉnh của tôi, và tôi đã bước vào nó, và nó hoạt động tốt - tải lên 60 vai trò cho người dùng tôi đang thử nghiệm. Tuy nhiên, tôi đã nhận thấy rằng GetRolesForUser được gọi trên mọi yêu cầu gọi User.IsInRole. Trong các ứng dụng khác tôi đã viết, nó chỉ gọi nó một lần, sau đó lưu trữ kết quả trong cookie. Vì một số lý do, bộ nhớ đệm không hoạt động cho ứng dụng này. Bất kỳ ý tưởng nào về lý do tại sao?

Trả lời

2

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

"Vấn đề khi bộ nhớ cache (hoặc không nhớ cache) trong RolePrincipal đã trải qua một số lần lặp thiết kế, và chúng tôi cuối cùng đã giải quyết trên chỉ bộ nhớ đệm cho phương pháp tiếp xúc bởi Giao diện IPrincipal (tức là IsInRole). "

+0

Vì vậy, cách tốt nhất để làm điều này là gì? Tôi muốn các vai trò để cache trong cookie. –

+0

Dùng thử và lỗi và cẩn thận chọn phương pháp nào để sử dụng, tôi đoán vậy. – Greg

+5

Liên kết bị hỏng. –

1

Điều này cũng đúng đối với tôi. Nó tiếp tục kêu gọi GetRolesForUser()

+0

Xem câu trả lời của Joao, nó hoạt động. – Lee

3

Tôi đã gặp vấn đề tương tự. Trong trường hợp của tôi, vấn đề là tôi đã thiết lập Context.User thành GenericPrincipal chứ không phải RolePrincipal. Vì vậy, thay vì:

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

này cố định cho tôi:

  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 
      } 

Các IsValidAuthCookie phương pháp kiểm tra cho null và trống rỗng:

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

UPDATE: Sau khi nâng cấp lên MVC5 .NET 4.5 roleManager ngừng hoạt động (không lưu vai trò trong cookie) vì vậy phải lưu bản thân mình:

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

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

Nơi mã này vào AuthenticationFilter và đăng ký nó trên toàn cầu. Xem here.

+0

Tôi đã tìm kiếm hàng giờ về vấn đề này và điều này đã sửa nó! Cảm ơn bạn rất nhiều vì đã gửi bài này! Bạn có thể trả lời một câu hỏi, tham chiếu cho phương thức IsValidAuthCookie hoặc lớp nào là mã được viết trong đó thực hiện phương thức đó? –

+0

Cảm ơn câu trả lời này đã giúp rất nhiều. Đây là giải pháp duy nhất giải quyết bộ nhớ đệm không còn hoạt động trong MVC 5 khi bạn triển khai RoleProvider. Tôi đặt cái này vào thuộc tính Authorization của chính tôi. – Lee

Các vấn đề liên quan