2011-11-01 1 views
8

Tôi có một ứng dụng MVC và tôi đã viết một roleprovider tùy chỉnh cho nó như:MVC tùy chỉnh roleprovider làm thế nào để móc nó lên đến HttpContext.Current.User.IsInRole ("myrole")

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Security; 
using VectorCheck.Models; 

namespace VectorCheck.Security 
{ 
    public class MyRoleProvider : RoleProvider 
    { 
     private VectorCheckRepository<User> _repository { get; set; } 

     public MyRoleProvider() 
     { 
      _repository = new VectorCheckRepository<User>(); 
     } 

     public MyRoleProvider(VectorCheckRepository<User> repository) 
     { 
      _repository = repository; 
     } 

     public override void AddUsersToRoles(string[] usernames, string[] roleNames) 
     { 
      throw new NotImplementedException(); 
     } 

     public override string ApplicationName 
     { 
      get 
      { 
       throw new NotImplementedException(); 
      } 
      set 
      { 
       throw new NotImplementedException(); 
      } 
     } 

     public override void CreateRole(string roleName) 
     { 
      throw new NotImplementedException(); 
     } 

     public override bool DeleteRole(string roleName, bool throwOnPopulatedRole) 
     { 
      throw new NotImplementedException(); 
     } 

     public override string[] FindUsersInRole(string roleName, string usernameToMatch) 
     { 
      throw new NotImplementedException(); 
     } 

     public override string[] GetAllRoles() 
     { 
      throw new NotImplementedException(); 
     } 

     public override string[] GetRolesForUser(string username) 
     { 
      var user = _repository.GetUser(username); 

      return new string[] { user.Role.Name }; 
     } 

     public override string[] GetUsersInRole(string roleName) 
     { 
      throw new NotImplementedException(); 
     } 

     public override bool IsUserInRole(string username, string roleName) 
     { 
      var user = _repository.GetUser(username); 

      return string.Compare(user.Role.Name, roleName, true) == 0; 
     } 

     public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames) 
     { 
      throw new NotImplementedException(); 
     } 

     public override bool RoleExists(string roleName) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

này hoạt động thực sự tốt với việc hạn chế quyền truy cập vào bộ điều khiển và hành động sử dụng:

[Authorize(Roles = "Administrator")] 

phía trên bộ điều khiển hoặc hành động.

Tôi cũng muốn giới hạn truy cập đến một số điều trong giao diện mặc dù sử dụng:

HttpContext.Current.User.IsInRole("Administrator") 

Phương pháp này không phải là một phần của roleprovider của tôi mặc dù vậy là không nhận được ghi đè.

Có ai biết cách thực hiện nó cho phương pháp này không?

Trả lời

11

Nếu bạn đã ghép RoleProvider của mình làm nhà cung cấp vai trò cho ứng dụng trong web.config, thì thao tác này sẽ hoạt động tự động; khung sẽ tạo một RolePrincipal cho người dùng được xác thực khi bắt đầu yêu cầu sẽ gọi phương thức GetRolesForUser trên nhà cung cấp vai trò của bạn, chuyển tên từ tên IIdentity làm tên người dùng.

Việc thực hiện khuôn khổ IsInRole(string role) phương pháp RolePrincipal 's là một cái gì đó như thế này (tôi đã thêm ý kiến)

public bool IsInRole(string role) 
{ 
    if (_Identity == null) 
     throw new ProviderException(SR.GetString(SR.Role_Principal_not_fully_constructed)); 

    if (!_Identity.IsAuthenticated || role == null) 
     return false; 
    role = role.Trim(); 
    if (!IsRoleListCached) { 
     _Roles.Clear(); 

     // here the RoleProvider is used to get the roles for the user 
     // and are cached in a collection on the RolePrincipal so that 
     // they are only fetched once per request 
     string[] roles = Roles.Providers[_ProviderName].GetRolesForUser(Identity.Name); 
     foreach(string roleTemp in roles) 
      if (_Roles[roleTemp] == null) 
       _Roles.Add(roleTemp, String.Empty); 

     _IsRoleListCached = true; 
     _CachedListChanged = true; 
    } 
    return _Roles[role] != null; 
} 

Đặt một breakpoint bên trong của phương pháp RoleProvider GetRolesForUser của bạn để đảm bảo rằng nó đang được gọi một cách chính xác và cũng kiểm tra IPrincipal (HttpContext.Current.User) để đảm bảo rằng nó thuộc loại RolePrincipal cho người dùng được xác thực.

+0

cung cấp Vai trò của tôi không chứa phương thức IsInRole mặc dù. Nó được kế thừa từ RoleProvider và có phương thức IsUserInRole. – AnonyMouse

+3

Phương thức IsInRole trên HttpContext.Current.User là một kiểu triển khai IPrincipal. khi bạn đã đăng ký RoleProvider và yêu cầu đến từ một người dùng đã được xác thực, IPrincipal sẽ là một cá thể của RolePrincipal. Bạn có thể thấy từ phương thức ở trên mà IsInRole trên RolePrincipal gọi phương thức GetRolesForUser của RoleProvider sao cho đó là phương thức mà bạn cần thiết lập một điểm ngắt để đảm bảo nó được gọi chính xác. –

5

Xin lỗi, tôi đến muộn với bữa tiệc ở đây;

Vì lợi ích của những người khác có cùng vấn đề - câu trả lời là Russ Cam's để tìm câu trả lời.

Trong trường hợp của tôi, vai trò tùy chỉnh của tôiQuản lý không có 'enabled = "true" và cacheRolesInCookie = "true". Điều này dường như dừng GetRolesForUser được gọi.

Mã Working Đối với web.config:

<roleManager defaultProvider="CustomUserRolesMVCRoleProvider" enabled="true" cacheRolesInCookie="true"> 

Really Good Hướng dẫn về chủ đề này tại http://www.brianlegg.com/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx