2015-11-26 24 views
1

過去一週裏,我一直在喋喋不休地談論這個問題,而且我在這裏或其他地方找到的答案似乎都沒有做任何事情。我有一個使用SimpleMembership的ASP.NET MVC5應用程序。我有一個名爲OrganisationsController控制器,具有以下屬性:SimpleMembership:AuthorizeAttribute和User.IsInRole無法正常工作

[Authorize(Roles = "Administrator")] 

我檢查了數據庫和我與登錄用戶確實是在「管理員」的角色。但是,Authorize屬性和User.IsInRole()都不會爲此角色返回「true」。

Authorize attribute not working with roles故建議

的AuthorizeAttribute調用存儲在HttpContext.User中所述的IPrincipal實例IsInRole方法。默認情況下,IPrincipal沒有角色,在這種情況下,IsInRole將始終返回false。這就是拒絕訪問您的操作的原因。

我使用了該答案中建議的以下代碼,但authTicket.UserData保持爲空。

protected void Application_AuthenticateRequest(Object sender, EventArgs e) 
{ 
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
    if (authCookie != null) 
    { 
     FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value); 
     string[] roles = authTicket.UserData.Split(','); 
     GenericPrincipal userPrincipal = new GenericPrincipal(new GenericIdentity(authTicket.Name), roles); 
     Context.User = userPrincipal; 
    } 
} 

我找不出什麼問題。爲什麼我可以登錄,但不能找到任何角色?

這裏的web.config中的一些相關部分:

<roleManager enabled="true" defaultProvider="SimpleRoleProvider"> 
     <providers> 
     <add name="SimpleRoleProvider" type="WebMatrix.WebData.SimpleRoleProvider, WebMatrix.WebData" /> 
     </providers> 
    </roleManager> 


    <membership defaultProvider="SimpleMembershipProvider"> 
     <providers> 
     <add name="SimpleMembershipProvider" type="WebMatrix.WebData.SimpleMembershipProvider, WebMatrix.WebData" /> 
     </providers> 
    </membership> 

    <authentication mode="Forms"> 
     <forms loginUrl="~/Account/Login" timeout="2880" cookieless="UseCookies" /> 
    </authentication> 

,這是InitializeSimpleMembershipAttribute我定義:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)] 
public sealed class InitializeSimpleMembershipAttribute : ActionFilterAttribute 
{ 
    private static SimpleMembershipInitializer _initializer; 
    private static object _initializerLock = new object(); 
    private static bool _isInitialized; 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     // Ensure ASP.NET Simple Membership is initialized only once per app start 
     LazyInitializer.EnsureInitialized(ref _initializer, ref _isInitialized, ref _initializerLock); 
    } 

    private class SimpleMembershipInitializer 
    { 
     public SimpleMembershipInitializer() 
     { 
      Database.SetInitializer<UsersContext>(null); 

      try 
      { 
       using (var context = new UsersContext()) 
       { 
        if (!context.Database.Exists()) 
        { 
         // Create the SimpleMembership database without Entity Framework migration schema 
         ((IObjectContextAdapter)context).ObjectContext.CreateDatabase(); 
        } 
       } 

       if (!WebSecurity.Initialized) 
       { 
        WebSecurity.InitializeDatabaseConnection("VerhaalLokaalDbContext", "UserProfile", "UserId", "UserName", autoCreateTables: true); 
       } 
      } 
      catch (Exception ex) 
      { 
       throw new InvalidOperationException("The ASP.NET Simple Membership database could not be initialized. For more information, please see http://go.microsoft.com/fwlink/?LinkId=256588", ex); 
      } 
     } 
    } 
} 

的InitializeSimpleMembershipAttribute只設在的AccountController。

這裏究竟發生了什麼?爲什麼找不到與數據庫中用戶相關的角色?

+0

看起來像你自己回答:「InitializeSimpleMembershipAttribute只在AccountController上設置」。你正在從OrganizationController請求一些東西,所以RoleProvider不會被初始化。 –

+0

它也不能在AccountController中工作,所以不能這樣做。 – Bas

回答

1

我們使用System.Web.Security.Roles.GetRolesForUser(...)調用,然後蠻力檢查交叉點的角色數組。在我們的例子中,這一切都發生在自定義AuthorizeAttribute類的'()調用中。擴展屬性可能不需要你,但我想給下面的代碼片段一些上下文。我們只使用主體來獲取用戶名。

例如,

var userRoles = System.Web.Security.Roles.GetRolesForUser(username); 
var allowedRoles = Roles.Split(','); // Roles is a property on the Authorize attribute 
var matches = userRoles.Intersect(allowedRoles).ToArray(); 
if (matches.Length > 0) // true if user is in an allowed role, otherwise it is not 

希望幫助!我相信有一種更有效的方法,我只是撣掉了我們現在使用了兩年的東西。