2011-11-01 5 views
8

私はMVCアプリを持っていると示したように、私はそれのためのカスタムroleproviderを書いた:HttpContext.Current.User.IsInRole(「myRoleの」)にそれをフックアップする方法roleprovider MVCのカスタム

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

をこれが実際に動作します

[Authorize(Roles = "Administrator")] 

コントローラやアクション以上:よく使用してコントローラとアクションへのアクセスを制限しています。

使用しているが、私はまた、ビューにいくつかのものへのアクセス制限をしたい:そう上書きなっていないが

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

このメソッドは、私のroleproviderの一部ではありません。

誰もこの方法でそれを行う方法を知っていますか?

答えて

11

roleProviderをweb.configのアプリケーションのロールプロバイダとして使用した場合は、自動的に機能します。フレームワークは、要求の開始時に、認証プロバイダのGetRolesForUserメソッドを呼び出し、ユーザ名としてIIdentityの名前を渡して認証されたユーザのためにRolePrincipalを作成します。

RolePrincipalIsInRole(string role)法の枠組みの実装は、このような何か(私は、コメントを追加しました)

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

が、それは正しくとも呼ばれていることを確認してくださいRoleProvider GetRolesForUser方法の内側にブレークポイントを設定していますIPrincipalHttpContext.Current.User)を検査して、認証されたユーザーのタイプがRolePrincipalであることを確認します。

+0

マイロールプロバイダでこのトピックに関する

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

本当に良いチュートリアルは、しかしメソッドIsInRoleが含まれていません。それはRoleProviderを継承し、メソッドIsUserInRoleを持ちます。 – AnonyMouse

+3

HttpContext.Current.UserのIsInRoleメソッドは、IPrincipalを実装する型です。 RoleProviderが登録されており、認証されたユーザーからリクエストが入った場合、IPrincipalはRolePrincipalのインスタンスになります。上のメソッドから、RolePrincipalのIsInRoleがRoleProviderのGetRolesForUserメソッドを呼び出すので、正しく呼び出されるようにブレークポイントを設定する必要があることがわかります。 –

5

申し訳ありませんが、私はここでパーティーに遅れています。

同じ問題を抱えている他の人々の利益のために - Russ Cam's答えは答えを見つけることにスポットです。

私のケースでは、私のカスタムroleManagerに 'enabled = "true"とcacheRolesInCookie = "true"がありませんでした。これは、GetRolesForUserが呼び出されるのを止めるように思えました。 web.configファイルのために

ワーキングコード:http://www.brianlegg.com/post/2011/05/09/Implementing-your-own-RoleProvider-and-MembershipProvider-in-MVC-3.aspx

関連する問題