Как заставить RoleProvider работать?

Это проект MVC 3. Просто для тестирования у меня есть

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

Прописываю в web.config. А затем, если я настрою стандартный SqlMemberShipProvider, что-то вроде следующего приведет к срабатыванию моего GetRolesForUser.

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

Однако я не хочу использовать стандартный SqlMemberShipProvider. Я определил собственный AuthorizeAttribute следующим образом, просто чтобы проверить:

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

Теперь следующее не приведет к срабатыванию MyRoleProvider.GetRolesForUser.

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

Вышеупомянутое вызовет MyAuthorize.AuthorizeCore и MyAuthorize.OnAuthorization, но не методы в MyRoleProvider. Какая связь между MemberShipProvider, RoleProvider и AuthorizedAttribute? Когда эти отношения определены или настроены?

Спасибо.


person Old Geezer    schedule 29.03.2012    source источник


Ответы (2)


Если вы не хотите использовать стандартный SqlRoleProvider, не настраивайте его. Обычно я это комментирую или удаляю.

Ваш конфиг будет выглядеть примерно так:

<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>
person GalacticCowboy    schedule 29.03.2012
comment
Я хочу удалить исходный пост. Должно быть, я где-то ошибся во время тестирования. Я начал все сначала и обнаружил, что MyRoleProvider вызывается, даже когда я использую атрибут MyAuthorize. Спасибо всем ответившим - person Old Geezer; 29.03.2012

Я не знаю, опечатка ли это, но это base.AuthorizeCore, который будет проверять наличие пользователя в ролях, поэтому

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

всегда возвращать true и не запускать базовый метод. Попробуйте удалить

bool result = true;
return result;

Вот фрагмент из источника MVC

    // 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;
    }
person Iridio    schedule 29.03.2012
comment
Спасибо. Это не опечатка. Я ловил поток событий, чтобы увидеть, где я могу вставить свой собственный код авторизации (я пытаюсь использовать учетную запись Google, которую я успешно реализовал в другом месте, независимо от ASP.NET MembershipProvider). На самом деле я не выяснил отношения между MemberShipProvider и атрибутом Authorize. Что это значит, если переопределить AuthorizeCore, но по-прежнему использовать стандартный MembershipProvider? Когда я использую свой RoleProvider, как мне перехватить AuthorizeCore? - person Old Geezer; 29.03.2012