2011-11-01 2 views
8

Mam app MVC i napisałem niestandardową roleprovider dla niego, jak pokazano:MVC niestandardowy roleprovider jak go podłączyć do 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(); 
     } 
    } 
} 

To naprawdę działa dobrze z ograniczeniem dostępu do kontrolerów i działań przy użyciu:

[Authorize(Roles = "Administrator")] 

powyżej kontrolera lub działania.

Chcę również ograniczony dostęp do niektórych rzeczy w widoku choć używając:

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

Metoda ta nie jest częścią mojego roleprovider chociaż tak nie jest uzyskiwanie nadpisane.

Czy ktoś wie, jak to zrobić dla tej metody?

Odpowiedz

11

Jeśli hakowałeś swojego RoleProvider jako dostawcę roli dla aplikacji w web.config, to powinno działać automatycznie; framework stworzy dla użytkownika uwierzytelnionego na początku żądania wywołanie metody RolePrincipal, która wywoła metodę GetRolesForUser na dostawcy roli, przekazując nazwę z IIdentity jako nazwę użytkownika.

Realizacja ramy IsInRole(string role) metody RolePrincipal „s jest coś takiego (dodałem komentarze)

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

Ustaw punkt przerwania wewnątrz swojego sposobu RoleProvider GetRolesForUser aby upewnić się, że jest on nazywany poprawnie, a także sprawdź, czy nie jest to IPrincipal (HttpContext.Current.User), aby upewnić się, że jest on typu RolePrincipal dla uwierzytelnionego użytkownika.

+0

mojego dostawcy rola nie zawiera metodę IsInRole chociaż. Dziedziczy po RoleProvider i ma metodę IsUserInRole. – AnonyMouse

+3

Metoda IsInRole na HttpContext.Current.User jest na typ implementujący IPrincipal. Jeśli masz zarejestrowanego RoleProvider, a żądanie pochodzi od uwierzytelnionego użytkownika, IPrincipal będzie instancją RolePrincipal. Z powyższej metody widać, że IsInRole na RolePrincipal wywołuje metodę GetRolesForUser RoleProvider, więc jest to ta, której potrzebujesz do ustawienia punktu przerwania, aby zapewnić, że jest poprawnie wywoływana. –

5

Przepraszam za spóźnienie na przyjęcie;

Dla korzyści innych osób z tym samym problemem - odpowiedź jest łatwa do znalezienia.

W moim przypadku moja niestandardowa rola Menedżer sesji nie miała "enabled =" true "i cacheRolesInCookie =" true ". To wydawało się zatrzymywać wywoływanie GetRolesForUser.

kod pracujących dla web.config:

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

Naprawdę dobry tutorial na ten temat w http://www.brianlegg.com/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx