RoleProvider dosn't work with custom IIdentity

2019-01-26 16:46发布

问题:

I'm using a custom IIdentity and IPrincipal in my ASP.NET MVC application via EF 4.3 as expalined here (and follow accepted answer's solution). Also, I have a custom RoleProvider. In local (using IIS Express), it works currectly. But now, when I upload the application on a real host, it seems all users are in "admin" role! e.g. I create a user that is not in role "admin", but it can access to all protected pages (that need "admin" role). e.g. Role.IsUserInRole always returns true. Have you any idea please? Can you help me? Is there any setting that I should to do in IIS?

回答1:

I explain that solution and it works for me. I don't now, may be you should rollback to the AuthenticateRequest event.If you want to try this way, you have to remove RoleManagerModule completely from your project. Try this and let me know if works or nop:

// in your module:

public void Init(HttpApplication context) {
    _application = context;
    // rollback this line:
    _application.AuthenticateRequest += ApplicationAuthenticateRequest;
}

// and in web.config

<!-- in system.web section: -->
</system.web>
  <!-- other stufs -->
  <httpModules>
    <remove name="RoleManager"/>
  </httpModules>
</system.web>

<!-- and in system.webServer section: -->
<system.webServer>
  <!-- other stufs -->
  <modules runAllManagedModulesForAllRequests="true">
    <remove name="RoleManager"/>
  </modules>
<system.webServer>


回答2:

If you want to keep using the default RoleManager, it gets difficult. I tried creating my own RoleManager by deriving from the default, without any luck. After 2 days trying several things, I ended up creating some extension methods for RolePrincipal:

public static bool IsEmployee(this RolePrincipal principal)
{
    if (IsAuthenticated())
        return principal.IsInRole("Employee");

    return false;
}

public static bool IsAdmin(this RolePrincipal principal)
{
    if (IsAuthenticated())
        return principal.IsInRole("Admin");

    return false;
}

Created a new WebViewPage class:

public abstract class BaseViewPage : WebViewPage
{
    public virtual new RolePrincipal User
    {
        get
        {
            if (base.User == null)
                return null;

            return (RolePrincipal)base.User; //Hard casting: If it goes wrong, it better goes wrong here
        }
    }
}

public abstract class BaseViewPage<TModel> : WebViewPage<TModel>
{
    public virtual new RolePrincipal User
    {
        get
        {
            if (base.User == null)
                return null;

            return (RolePrincipal)base.User; //Hard casting: If it goes wrong, it better goes wrong here
        }
    }
}

Modified the web.config in the views folder:

<pages pageBaseType="MyCompany.MyProject.BaseViewPage">

And all my Controllers derive from my BaseController:

public abstract class BaseController : Controller
{
    protected virtual new RolePrincipal User
    {
        get { return HttpContext.User as RolePrincipal; }
    }
}

Downside is that the methods query my database everytime they get called. I'm using MVC 4 btw

Hope this helps anyone