Почему AuthorizeAttribute перенаправляет на страницу входа в систему при сбоях аутентификации и авторизации?

В ASP.NET MVC вы можете пометить метод контроллера 9X_login с помощью AuthorizeAttribute, например:

[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
    // ...
}

Это означает, что, если 9X_auth текущий авторизованный пользователь не имеет 9X_user-authentication роли CanDeleteTags, метод контроллера никогда 9X_authenticate не будет вызван.

К сожалению, при сбоях AuthorizeAttribute возвращает 9X_asp-net-mvc HttpUnauthorizedResult, который всегда возвращает код состояния 9X_authentication HTTP 401. Это вызывает перенаправление на 9X_logon страницу входа.

Если пользователь не вошел 9X_asp-mvc в систему, это имеет смысл. Однако, если 9X_login пользователь уже вошел в систему, но не в требуемой 9X_asp.net-mvc роли, отправить его обратно на страницу 9X_authorization входа в систему будет затруднительно.

Похоже, что 9X_asp.net-mvc AuthorizeAttribute объединяет аутентификацию и авторизацию.

Это 9X_asp.net-mvc похоже на некоторую оплошность в ASP.NET 9X_asp-net-mvc MVC, или я что-то упускаю?

Мне пришлось приготовить 9X_authorization DemandRoleAttribute, разделяющий их. Когда пользователь не 9X_asp.mvc аутентифицирован, он возвращает HTTP 401, отправляя 9X_authenticate его на страницу входа. Когда пользователь 9X_authenticate вошел в систему, но не в требуемой роли, вместо 9X_authorisation этого он создает NotAuthorizedResult. В настоящее время это 9X_auth перенаправляет на страницу с ошибкой.

Конечно, мне 9X_authorization не нужно было этого делать?

273
3

  • Мне нравится твое решение, Роджер. Даже если вы этого не сделае ...
4
Общее количество ответов: 4

Ответ #1

Ответ на вопрос: Почему AuthorizeAttribute перенаправляет на страницу входа в систему при сбоях аутентификации и авторизации?

Когда он был впервые разработан, System.Web.Mvc.AuthorizeAttribute 9X_authenticate поступал правильно - более старые версии 9X_authorisation спецификации HTTP использовали код состояния 9X_authenticate 401 как для «неавторизованный», так и «неавторизованный».

Из 9X_authenticate исходной спецификации:

Если запрос уже включал 9X_auth учетные данные авторизации, то ответ 401 9X_asp-mvc указывает на то, что в авторизации для этих 9X_authorization учетных данных было отказано.

На самом деле, вы 9X_asp-mvc можете увидеть путаницу прямо здесь - здесь 9X_asp-net-mvc используется слово «авторизация», когда 9X_auth оно означает «аутентификация». Однако в 9X_asp-net-mvc повседневной практике имеет смысл возвращать 9X_mvc.net 403 Forbidden, когда пользователь аутентифицирован, но 9X_asp-mvc не авторизован. Маловероятно, что у пользователя 9X_asp-net-mvc будет второй набор учетных данных, которые 9X_user-authentication предоставят ему доступ - все вокруг плохое.

Рассмотрим 9X_asp.net-mvc большинство операционных систем - когда 9X_authenticate вы пытаетесь прочитать файл, к которому 9X_authenticate у вас нет прав доступа, вам не отображается 9X_mvc.net экран входа в систему!

К счастью, спецификации 9X_asp.net-mvc HTTP были обновлены (июнь 2014 г.), чтобы 9X_authorisation устранить двусмысленность.

Из «Протокол передачи 9X_auth гипертекста (HTTP / 1.1): аутентификация» (RFC 9X_auth 7235):

Код состояния 401 (Неавторизован) указывает 9X_asp-mvc на то, что запрос не был применен, поскольку 9X_asp-mvc ему не хватает действительных учетных данных 9X_authorization для аутентификации для целевого ресурса.

Из 9X_asp.net.mvc «Протокол передачи гипертекста (HTTP / 1.1): семантика 9X_mvc.net и контент» (RFC 7231):

Код состояния 403 9X_authorisation (Запрещено) указывает на то, что сервер 9X_user-authentication понял запрос, но отказывается его авторизовать.

Интересно, что 9X_auth на момент выпуска ASP.NET MVC 1 поведение 9X_authorisation AuthorizeAttribute было правильным. Теперь 9X_logon поведение неверное - спецификация HTTP / 1.1 9X_asp.net.mvc была исправлена.

Вместо того, чтобы пытаться 9X_login изменить перенаправления страницы входа 9X_asp-net-mvc в ASP.NET, проще решить проблему в источнике. Вы 9X_asp.mvc можете создать новый атрибут с тем же именем 9X_asp-mvc (AuthorizeAttribute) в пространстве имен вашего веб-сайта по умолчанию (это очень важно), тогда компилятор 9X_asp.net.mvc автоматически подберет его вместо стандартного 9X_user-authentication MVC. Конечно, вы всегда можете дать атрибуту 9X_authenticate новое имя, если вы предпочитаете такой подход.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.Request.IsAuthenticated)
        {
            filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}

312
3

  • @DePeter в спецификации ничего не говорится о перенаправлении, так почему перенаправление я ...

Ответ #2

Ответ на вопрос: Почему AuthorizeAttribute перенаправляет на страницу входа в систему при сбоях аутентификации и авторизации?

Добавьте это в свою функцию Login Page_Load:

// User was redirected here because of authorization section
if (User.Identity != null && User.Identity.IsAuthenticated)
    Response.Redirect("Unauthorized.aspx");

Когда 9X_asp-mvc пользователь перенаправлен туда, но уже 9X_user-authentication вошел в систему, отображается неавторизованная 9X_mvc.net страница. Если они не вошли в систему, он 9X_asp.net.mvc проваливается и показывает страницу входа.

24
3

  • В соответствии с вашим решением, если вы уже вошли в систему и перешли на страницу входа, введя URL-адрес ... это приведет вас к неавторизованной странице. что ...

Ответ #3

Ответ на вопрос: Почему AuthorizeAttribute перенаправляет на страницу входа в систему при сбоях аутентификации и авторизации?

К сожалению, вы имеете дело с поведением 9X_asp.mvc аутентификации форм ASP.NET по умолчанию. Здесь 9X_authorization обсуждается обходной путь (я не пробовал):

http://www.codeproject.com/KB/aspnet/Custon401Page.aspx

(Это 9X_authenticate не относится к MVC)

Я думаю, что в большинстве 9X_mvc.net случаев лучшим решением является ограничение 9X_asp.net-mvc доступа к неавторизованным ресурсам до того, как 9X_asp.net-mvc пользователь попытается туда попасть. Удалив 9X_asp.mvc / закрасив серым цветом ссылку или кнопку, которая 9X_asp.net.mvc может привести их на эту неавторизованную 9X_authorization страницу.

Возможно, было бы неплохо иметь 9X_mvc.net дополнительный параметр для атрибута, чтобы 9X_logon указать, куда перенаправлять неавторизованного 9X_asp-mvc пользователя. Но пока что я смотрю на AuthorizeAttribute 9X_authenticate как на подстраховку.

4
1

  • Мне все еще нужно запретить пользователю переходить непосредственно к URL-адресу, для чего и предназначен этот атрибут. Я не очень доволен решением Custom 401 (кажется немного глобальным), поэтому я попробую смоделировать с ...

Ответ #4

Ответ на вопрос: Почему AuthorizeAttribute перенаправляет на страницу входа в систему при сбоях аутентификации и авторизации?

Мне всегда казалось, что в этом есть смысл. Если 9X_authentication вы вошли в систему и пытаетесь перейти на 9X_authorisation страницу, для которой требуется роль, которой 9X_asp-mvc у вас нет, вы будете перенаправлены на экран 9X_asp.net.mvc входа в систему с просьбой войти в систему 9X_authorisation с пользователем, у которого есть роль.

Вы 9X_asp.net.mvc можете добавить логику на страницу входа, которая 9X_asp.net-mvc проверяет, аутентифицирован ли пользователь 9X_authentication уже. Вы можете добавить дружелюбное сообщение, объясняющее, почему 9X_user-authentication они снова оказались в тупике.

4
1

  • Мне кажется, что большинство людей не склонны иметь более одной идентичности для одного веб-приложения. Если они это сделают, то они достаточно умны, чтобы подумать: «У моего текущего идентификатора не ...