Подтвердить что ты не робот

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

Я использую атрибут Authorize следующим образом:

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

РЕДАКТИРОВАТЬ: Извините, я, по-видимому, не понял эту проблему полностью.

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

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

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

  • Создайте свой собственный 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.

Ответ 2

Вы можете сделать это двумя способами:

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

    [HandleError (ExceptionType = typeof (UnAuthorizedException),  View = "UnauthorizedError" )]

Вы можете указать несколько разных ExceptionTypes и представлений

  1. Создайте пользовательский ActionFilter, проверьте наличие учетных данных и переадресовывайте его на контроллер, если пользователь несанкционирован: http://web.archive.org/web/20090322055514/http://msdn.microsoft.com/en-us/library/dd381609.aspx li >

Ответ 3

Возможно, код статуса 403 более подходит на основе вашего вопроса (пользователь идентифицирован, но их учетная запись недостаточно привилегирована). 401 - это случай, когда вы не знаете, какие у пользователя есть привилегии.

Ответ 4

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

Ответ 5

Просто переопределите метод HandleUnauthorizedRequest AuthorizeAttribute. Если этот метод вызывается, но пользователь IS аутентифицирован, вы можете перенаправить на свою "несанкционированную" страницу.

public class CustomAuthorizeAttribute : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Area = "", Controller = "Error", Action = "Unauthorized" }));
        }
        else
        {
            base.HandleUnauthorizedRequest(filterContext);
        }
    }
}