首页 文章

SimpleMembership:AuthorizeAttribute和User.IsInRole不起作用

提问于
浏览
1

在过去的一周里,我一直在绞尽脑汁,我在这里或其他地方找到的答案似乎都没有做任何事情 . 我有一个使用SimpleMembership的ASP.NET MVC5应用程序 . 我有一个名为OrganisationsController的控制器,它具有以下属性:

[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上设置 .

到底发生了什么?为什么不能找到定义并绑定到数据库中用户的角色?

1 回答

  • 1

    我们使用 System.Web.Security.Roles.GetRolesForUser(...) 调用然后强制检查交叉点的那些角色数组 . 在我们的例子中,这一切都发生在自定义 AuthorizeAttribute classes'()调用中 . 您可能不需要扩展属性,但我想为以下代码片段提供一些上下文 . 我们只使用了主体来获取用户名 .

    例如 . ,

    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
    

    希望有所帮助!我确信有一种更有效的方式,我只是把我们已经使用了两年的东西拂去了 .

相关问题