В ASP.NET MVC вы можете пометить метод контроллера AuthorizeAttribute
следующим образом:
[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
// ...
}
Это означает, что, если зарегистрированный в данный момент пользователь не имеет роли «CanDeleteTags», метод контроллера никогда не будет вызываться.
К сожалению, для сбоев AuthorizeAttribute
возвращается HttpUnauthorizedResult
, что всегда возвращает код состояния HTTP 401. Это вызывает перенаправление на страницу входа.
Если пользователь не вошел в систему, это имеет смысл. Тем не менее, если пользователь уже вошел в систему, но не в требуемой роли, отправлять их обратно на страницу входа в систему сложно.
Похоже, что AuthorizeAttribute
объединяет аутентификацию и авторизацию.
Это похоже на упущение в ASP.NET MVC, или я что-то упустил?
Я должен был приготовить что-то, DemandRoleAttribute
что разделяет их. Когда пользователь не аутентифицирован, он возвращает HTTP 401, отправляя его на страницу входа. Когда пользователь вошел в систему, но не в требуемой роли, он создает NotAuthorizedResult
вместо этого. В настоящее время это перенаправляет на страницу ошибки.
Конечно, я не должен был этого делать?
источник
Ответы:
Когда он был впервые разработан, System.Web.Mvc.AuthorizeAttribute действовал правильно - более ранние версии спецификации HTTP использовали код состояния 401 как для «неавторизованного», так и «неаутентифицированного».
Из оригинальной спецификации:
На самом деле, вы можете увидеть путаницу прямо здесь - она использует слово «авторизация», когда оно означает «аутентификация». Однако в повседневной практике имеет смысл возвращать 403 Запрещено, когда пользователь аутентифицирован, но не авторизован. Маловероятно, что у пользователя будет второй набор учетных данных, который предоставит ему доступ - плохой пользовательский опыт со всех сторон.
Рассмотрим большинство операционных систем - когда вы пытаетесь прочитать файл, к которому у вас нет прав доступа, вам не показывается экран входа!
К счастью, спецификации HTTP были обновлены (июнь 2014 г.), чтобы устранить неоднозначность.
Из «Гипертекстового транспортного протокола (HTTP / 1.1): аутентификация» (RFC 7235):
Из «Протокола передачи гипертекста (HTTP / 1.1): семантика и контент» (RFC 7231):
Интересно, что на момент выпуска ASP.NET MVC 1 поведение AuthorizeAttribute было правильным. Теперь поведение некорректно - спецификация HTTP / 1.1 была исправлена.
Вместо того, чтобы пытаться изменить перенаправления страницы входа в ASP.NET, проще просто устранить проблему у источника. Вы можете создать новый атрибут с таким же именем (
AuthorizeAttribute
) в пространстве имен вашего сайта по умолчанию (это очень важно), тогда компилятор автоматически подберет его вместо стандартного MVC. Конечно, вы всегда можете дать атрибуту новое имя, если вы предпочитаете такой подход.источник
filterContext.HttpContext.User.Identity.IsAuthenticated
вы можете просто проверитьfilterContext.HttpContext.Request.IsAuthenticated
, которая поставляется со встроенными нулевыми проверками. См. Stackoverflow.com/questions/1379566/…Добавьте это к вашей функции Login Page_Load:
Когда пользователь перенаправлен туда, но уже вошел в систему, отображается неавторизованная страница. Если они не вошли в систему, он проваливается и показывает страницу входа.
источник
if (User.Identity != null && User.Identity.IsAuthenticated) return RedirectToRoute("Unauthorized");
где Unauthorized - это определенное имя маршрута.Я всегда думал, что это имеет смысл. Если вы вошли в систему и пытаетесь перейти на страницу, для которой не нужна роль, вы попадаете на экран входа в систему с просьбой войти в систему с пользователем, у которого есть эта роль.
Вы можете добавить логику на страницу входа, которая проверяет, прошел ли пользователь аутентификацию. Вы можете добавить дружеское сообщение, которое объясняет, почему они снова были обмануты.
источник
К сожалению, вы имеете дело с поведением по умолчанию проверки подлинности форм ASP.NET. Здесь есть обходной путь (я не пробовал):
http://www.codeproject.com/KB/aspnet/Custon401Page.aspx
(Это не специфично для MVC)
Я думаю, что в большинстве случаев лучшим решением является ограничение доступа к неавторизованным ресурсам до того, как пользователь попытается туда добраться. Удаляя / скрывая ссылку или кнопку, которая может привести их к этой неавторизованной странице.
Вероятно, было бы неплохо иметь дополнительный параметр в атрибуте, чтобы указать, куда перенаправлять неавторизованного пользователя. Но пока я смотрю на AuthorizeAttribute как на сеть безопасности.
источник
Попробуйте это в вашем обработчике Application_EndRequest вашего файла Global.ascx.
источник
Если вы используете aspnetcore 2.0, используйте это:
источник
В моем случае проблема заключалась в том, что «спецификация HTTP использовала код состояния 401 как для« неавторизованного », так и« неавторизованного »». Как сказал ShadowChaser.
Это решение работает для меня:
источник