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

Можно ли использовать RedirectToAction() внутри пользовательского класса AuthorizeAttribute?

Используя ASP.Net MVC 2, можно ли использовать метод RedirectToAction() Controller внутри класса, основанного на классе AuthorizeAttribute?

public class CustomAttribute : AuthorizeAttribute {
    protected override bool AuthorizeCore(HttpContextBase context) {
        // Custom authentication goes here
        return false;
    }

    public override void OnAuthorization(AuthorizationContext context) {
        base.OnAuthorization(context);

        // This would be my ideal result
        context.Result = RedirectToAction("Action", "Controller");
    }
}

Я ищу способ перенаправить пользователя на конкретный контроллер/действие, когда они не выполняют аутентификацию, а не возвращают их на страницу входа. Возможно ли иметь перенаправленный URL-адрес для этого контроллера/действия, а затем использовать RedirectResult()? Я пытаюсь избежать соблазна просто скопировать URL-адрес.

4b9b3361

Ответ 1

Вы можете/должны переопределять HandleUnauthorizedRequest вместо OnAuthorization. Здесь используется реализация по умолчанию:

    protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
        // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
        filterContext.Result = new HttpUnauthorizedResult();
    }

Вы не можете использовать Controller.RedirectToAction, но вы можете вернуть новый RedirectToRouteResult.

Итак, вы можете сделать:

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) {
        // Returns HTTP 401 - see comment in HttpUnauthorizedResult.cs.
        filterContext.Result = new RedirectToRouteResult(
                                   new RouteValueDictionary 
                                   {
                                       { "action", "ActionName" },
                                       { "controller", "ControllerName" }
                                   });
    }

Ответ 2

Вы можете сделать что-то вроде этого:

var routeValues = new RouteValueDictionary();
routeValues["controller"] = "ControllerName";
routeValues["action"] = "ActionName";
//Other route values if needed.
context.Result = new RedirectToRouteResult(routeValues);

Это так, как это делает инфраструктура, когда вы вызываете "RedirectToAction()" в своем контроллере.

Ответ 3

Если кто-то еще интересуется этим вопросом. Это можно решить более простым способом (по крайней мере с использованием MVC 3, не знаю о MVC 2):

Просто создайте небольшой закрытый контроллер в своем пользовательском атрибуте AuthorizeAttribute:

    private class RedirectController : Controller
    {
        public ActionResult RedirectWhereever()
        {
            return RedirectToAction("Action", "Controller");
        }

    }

Это можно легко использовать в методе HandleUnauthorizedRequest (см. ответ Craigs):

filterContext.Result = (new RedirectController()).RedirectWhereever();