Как я подаю страницу Unauthorized, когда пользователь не находится в Авторизованных Ролях?

Я использую Authorize припишите как это:

[Authorize (Roles="Admin, User")]
Public ActionResult Index(int id)
{
    // blah
}

Когда пользователь не находится в указанных ролях, я получаю ошибочную страницу (ресурс, не найденный). Таким образом, я поместил HandleError атрибут в также.

[Authorize (Roles="Admin, User"), HandleError]
Public ActionResult Index(int id)
{
    // blah
}

Теперь это переходит к Странице входа в систему, если пользователь не находится в указанных ролях.

Как я заставляю это переходить к странице Unauthorized вместо страницы входа в систему, когда пользователь не встречает одну из необходимых ролей? И если другая ошибка происходит, как я отличаю ту ошибку от Несанкционированной ошибки и обрабатываю ее по-другому?

41
задан Robert Harvey 23 February 2010 в 22:50
поделиться

3 ответа

Добавьте что-то вроде этого в ваш web.config:

<customErrors mode="On" defaultRedirect="~/Login">
     <error statusCode="401" redirect="~/Unauthorized" />
     <error statusCode="404" redirect="~/PageNotFound" />
</customErrors>

Вы, очевидно, должны создать /PageNotFound и /Unauthorized маршруты, действия и представления.

EDIT: Извините, я, видимо, не до конца понял суть проблемы.

Проблема в том, что когда выполняется фильтр AuthorizeAttribute, он решает, что пользователь не соответствует требованиям (он/она может быть залогинен, но не в правильной роли). Поэтому он устанавливает код состояния ответа на 401. Это перехватывается модулем FormsAuthentication, который затем выполняет перенаправление.

Я вижу две альтернативы:

  1. Отключить defaultRedirect.

  2. Создать свой собственный IAuthorizationFilter. Производное от AuthorizeAttribute и переопределите HandleUnauthorizedRequest. В этом методе, если пользователь аутентифицирован, сделайте перенаправление на /Unauthorized

Мне не нравится ни то, ни другое: функциональность defaultRedirect хороша, но это не то, что вы хотите реализовать самостоятельно. Второй подход приводит к тому, что пользователю будет показана визуально корректная страница "Вы не авторизованы", но коды состояния HTTP не будут соответствовать желаемому 401.

Я не знаю достаточно о HttpModules, чтобы сказать, можно ли обойти это с помощью сносного хака.

EDIT 2: Как насчет реализации собственного IAuthorizationFilter следующим образом: скачайте код MVC2 с CodePlex и "позаимствуйте" код для AuthorizeAttribute. Измените метод OnAuthorization на следующий

    public virtual void OnAuthorization(AuthorizationContext filterContext)
    {
        if (AuthorizeCore(filterContext.HttpContext))
        { 
            HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
            cachePolicy.SetProxyMaxAge(new TimeSpan(0));
            cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
        }
        // Is user logged in?
        else if(filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            // Redirect to custom Unauthorized page
            filterContext.Result = new RedirectResult(unauthorizedUrl);
        } 
        else {
            // Handle in the usual way
            HandleUnauthorizedRequest(filterContext);
        }
    }

где unauthorizedUrl является либо свойством фильтра, либо считывается из Web.config.

Можно также наследоваться от AuthorizeAttribute и переопределить OnAuthorization, но в итоге придется написать пару приватных методов, которые уже есть в AuthorizeAttribute.

27
ответ дан 27 November 2019 в 00:54
поделиться

И HttpUnauthorizedResult (это повторное использование AuthorizeAtrribute ) просто устанавливает StatusCode равным 401. Так что, вероятно, вы можете настроить страницу 401 в IIS или настраиваемые страницы ошибок в web.config. Конечно, вы также должны убедиться, что для доступа к вашей настраиваемой странице ошибок не требуется авторизация.

3
ответ дан 27 November 2019 в 00:54
поделиться

В Ruby и Perl 6 это было названо «splat», и я думаю, что большинство людей из этих сообществ поймут, что вы имеете в виду, если вы назовете это так.

В руководстве Python используется фраза «распаковка перечислять аргументов», которая является длинной и описательной. Я не слышал никакого другого конкретного имени в Пайтоне.

-121--622556-

Единственный раз, когда я знаю, что вы должны вручную поднять StopIteration , это когда вы реализуете метод next () в классе, чтобы сообщить, что итератор завершен. Для генераторов (функции с выдают операторов в них) конец функции или оператор возврата правильно инициирует StopIteration для вас.

-121--3572314-

Это можно сделать двумя способами:

  1. Укажите ошибку в атрибуте HandleError и задайте представление, которое должно отображаться:

    [HandleError (ExcepityType = тип (UnAuthorizedException), Представление = «UnauthorizedError»)]

Вы можете определить несколько различных ExceptionTypes, и взгляды

  1. Создают обычай ActionFilter, проверяют там на полномочия и перенаправление диспетчеру, если пользователь лишен полномочий.: http://web.archive.org/web/20090322055514/http://msdn.microsoft.com/en-us/library/dd381609.aspx
7
ответ дан 27 November 2019 в 00:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: