Question

This is a MVC 3 project. Just for testing, I have

public class MyRoleProvider : RoleProvider
{
    public override string[] GetRolesForUser(string username)
    {
        return new string[] { "0", "1", "2", "4" };
    }

    public override bool IsUserInRole(string username, string roleName)
    {
        bool result = true;
        return result;
    }

I register it in web.config. And then, if I configure the standard SqlMemberShipProvider, something like the following will cause my GetRolesForUser to fire.

[Authorize(Roles="4")]
public class AdminController : Controller
{  //...

However, I don't want to use the standard SqlMemberShipProvider. I defined by own AuthorizeAttribute as follows, just to test:

public class MyAuthorize : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool result = true;
        return result;
        return base.AuthorizeCore(httpContext);
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }
}

Now, the following will not cause MyRoleProvider.GetRolesForUser to fire anymore.

[MyAuthorize(Roles="4")]
public class AdminController : Controller
{  //...

The above will trigger MyAuthorize.AuthorizeCore and MyAuthorize.OnAuthorization but not the methods in MyRoleProvider. What is the relationship between the MemberShipProvider, the RoleProvider and the AuthorizedAttribute? When are these relationships defined or configured?

Thanks.

Était-ce utile?

La solution

If you don't want to use the standard SqlRoleProvider, don't configure it. I usually comment it out or delete it.

Your config will look something like this:

<roleManager defaultProvider="MyRoleProvider" enabled="true">
  <providers>
    <clear />
    <!--<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
    <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />-->
    <add name="MyRoleProvider" type="Full.Namespace.Of.MyRoleProvider" applicationName="/" />
  </providers>
</roleManager>

Autres conseils

I don't know if it's a typo, but it's base.AuthorizeCore that will check for user in roles so

protected override bool AuthorizeCore(HttpContextBase httpContext)
{
    bool result = true;
    return result;
    return base.AuthorizeCore(httpContext);
}

return always true and don't fire the base method. Try to remove

bool result = true;
return result;

Here is a snippet from the MVC source

    // This method must be thread-safe since it is called by the thread-safe OnCacheAuthorization() method.
    protected virtual bool AuthorizeCore(HttpContextBase httpContext) {
        if (httpContext == null) {
            throw new ArgumentNullException("httpContext");
        }

        IPrincipal user = httpContext.User;
        if (!user.Identity.IsAuthenticated) {
            return false;
        }

        if (_usersSplit.Length > 0 && !_usersSplit.Contains(user.Identity.Name, StringComparer.OrdinalIgnoreCase)) {
            return false;
        }

        if (_rolesSplit.Length > 0 && !_rolesSplit.Any(user.IsInRole)) {
            return false;
        }

        return true;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top