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

Перенаправление на другую страницу, когда пользователь не авторизовался в asp.net mvc3

Я читал

Как легко перенаправить, если не аутентифицироваться в MVC 3? и Перенаправить на страницу AccessDenied, когда пользователь не авторизовался, но ссылка из ответа (означает http://wekeroad.com/2008/03/12/aspnet-mvc-securing-your-controller-actions/) не работает.

Я положил

[Authorize(Users = "test")]
    public class RestrictedPageController: Controller
    {

        public ActionResult Index()
        {
           return View();
        }

 ....
    }

И в моем web.config я уже

 <authentication mode="Forms">
      <forms loginUrl="~/Account/LogOn" timeout="2880" />
 </authentication>

соответственно qaru.site/info/288279/...

Но когда я хочу получить доступ к /RestrictedPage/Index, он должен перенаправить меня на другую страницу (с другого контроллера). Вместо этого появляется ошибка:

Server Error in '/Project' Application.

The view 'LogOn' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Account/LogOn.aspx
~/Views/Account/LogOn.ascx
~/Views/Shared/LogOn.aspx
~/Views/Shared/LogOn.ascx
~/Views/Account/LogOn.cshtml
~/Views/Account/LogOn.vbhtml
~/Views/Shared/LogOn.cshtml
~/Views/Shared/LogOn.vbhtml

Прежде чем войти в систему, форма страницы Logon появится правильно, но при доступе к странице /RestrictedPage/Index появится указанная выше ошибка. Я могу войти в систему с другим пользователем, которому разрешен доступ к странице RestrictedPage.

Где моя ошибка и как перенаправление настроек?

4b9b3361

Ответ 1

По умолчанию атрибут Authorize ведет себя так, что когда пользователь не аутентифицирован или не аутентифицирован, но не авторизован, он устанавливает код состояния 401 (UnAuthorized). Когда фильтр устанавливает код состояния 401, структура ASP.NET проверяет, включен ли веб-сайт для проверки подлинности форм, и если он затем перенаправляется к параметру loginUrl, установленному там.

Если вы хотите изменить это поведение, скажите, что вы хотите перенаправить пользователя на контроллер AccessDenied, если пользователь аутентифицирован, но не авторизован, вам необходимо расширить атрибут Authorize и переопределить метод HandleUnauthorizedRequest.

Например,

public class CustomAuthorize: AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new HttpUnauthorizedResult();
        }
        else
        {
           filterContext.Result = new RedirectToRouteResult(new 
               RouteValueDictionary(new { controller = "AccessDenied" }));
        }
    }
}

Вы можете переопределить HandleUnauthorizedRequest в соответствии с вашими потребностями, а затем вы должны пометить действия контроллера, чтобы использовать атрибут CustomAuthorize вместо встроенного.

Ответ 2

Мне нравится Mark Answer,
но я не хочу менять все свои атрибуты действия
от [Авторизовать] до [CustomAuthorize]

Я редактирую действие Login() на AccountController
и проверьте Request.IsAuthenticated перед представлением просмотра
Я думаю, если аутентифицированный пользователь перейдет на /Account/Logon,
Я перенаправляюсь на /Error/AccessDenied.

    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        if (Request.IsAuthenticated)
        {
            return RedirectToAction("AccessDenied", "Error");
        }

        ViewBag.ReturnUrl = returnUrl;

        return View();
    }

Ответ 3

Поместите "/Account/LogOn" вместо "~/Account/LogOn"

Ответ 4

Да, это правильно, как вы упомянули в web.config

<forms loginUrl="~/Account/LogOn" timeout="2880" />

перенаправление ищет Контроллер учетной записи и LogOn actionresult. Если вы хотите перенаправить свою страницу, измените ее вместо учетной записи и входа в систему

Ответ 5

Поскольку я не хотел переопределять AuthorizeAttribute, я использовал фильтр

public class RedirectFilter : ActionFilterAttribute
{
   public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        if (!IsAuthorized(filterContext))
        {
            filterContext.Result =
                new RedirectToRouteResult(new RouteValueDictionary(new {controller = "AccessDenied"}));
        }
    }

    private bool IsAuthorized(ActionExecutingContext filterContext)
    {
        var descriptor = filterContext.ActionDescriptor;
        var authorizeAttr = descriptor.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute;

        if (authorizeAttr != null)
        {
            if(!authorizeAttr.Users.Contains(filterContext.HttpContext.User.ToString()))
            return false;
        }
        return true;

    }
}