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

ASP.NET MVC перенаправляет на страницу с запретом доступа с помощью поставщика настраиваемых ролей

Я создаю пользовательский поставщик роли, и я устанавливаю атрибут Authorize, определяющий роль в моем контроллере, и он работает нормально, например:

[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...

Но когда пользователь не имеет доступа к этому контроллеру, он перенаправляется на страницу входа. Как я могу перенаправить его на страницу "AcessDenied.aspx"?

4b9b3361

Ответ 1

[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller

AccessDeniedAuthorizeAttribute.cs:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        if(filterContext.Result is HttpUnauthorizedResult)
        {
            filterContext.Result = new RedirectResult("~/AcessDenied.aspx");
        }
    }
}

Ответ 2

Здесь мое решение, основанное на eu-ge-ne ответе. Mine правильно перенаправляет пользователя на страницу входа в систему, если они не вошли в систему, но на странице "Отказано в доступе", если они вошли в систему, но неавторизированы для просмотра этой страницы.

[AccessDeniedAuthorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller

AccessDeniedAuthorizeAttribute.cs:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
        if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult("~/Account/Logon");
            return;
        }

        if (filterContext.Result is HttpUnauthorizedResult)
        {
            filterContext.Result = new RedirectResult("~/Account/Denied");
        }
    }
}

AccountController.cs:

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

Views/Account/Denied.cshtml: (синтаксис Razor)

@{
    ViewBag.Title = "Access Denied";
}

<h2>@ViewBag.Title</h2>

Sorry, but you don't have access to that page.

Ответ 3

Посмотрите tvanfosson ответ от этот очень похожий вопрос. Это то, что я делаю (спасибо tvanfosson), так что теперь я просто должен сказать:

[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...

Если пользователь не находится в роли, он получит это представление, указанное ViewName.

Ответ 4

Небольшое улучшение ответа Мэтта, избегая необходимости жестко закодировать страницу входа в систему и, при желании, настроить доступ запрещенного вида в атрибуте:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public string AccessDeniedViewName { get; set; }

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

        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
            filterContext.Result is HttpUnauthorizedResult)
        {
            if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
                AccessDeniedViewName = "~/Account/AccessDenied";

            filterContext.Result = new RedirectResult(AccessDeniedViewName);
        }
    }
}

Ответ 5

Перенаправление не всегда лучшее решение

Использовать стандартный http-код 403:

return new HttpStatusCodeResult(HttpStatusCode.Forbidden);

Ответ 6

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);

            if (filterContext.Result is HttpUnauthorizedResult && WebSecurity.IsAuthenticated)
            {
                filterContext.Result = new RedirectResult("~/Account/AccessDenied");
            }
        }
    }

Ответ 7

Я построил на Vic ответ, чтобы разрешить мне иметь другую страницу отказа от доступа для каждой из областей приложения. Сделал ли это, вернув вместо этого RedirectToRouteResult, который вместо перенаправления на URL-адрес относительно корня приложения перенаправляет его на текущий контроллер области и действие:

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public string AccessDeniedController { get; set; }
    public string AccessDeniedAction { get; set; }

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

        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
            filterContext.Result is HttpUnauthorizedResult)
        {
            if (String.IsNullOrWhiteSpace(AccessDeniedController) || String.IsNullOrWhiteSpace(AccessDeniedAction))
            {
                AccessDeniedController = "Home";
                AccessDeniedAction = "AccessDenied";
            }

            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = AccessDeniedController, Action = AccessDeniedAction }));
        }
    }
}

Ответ 8

Просто небольшое обновление для Вика Алькасара, Добавлены сведения о URL-адресе запроса в перенаправлении Таким образом, можно регистрировать сведения об отказе доступа и кем, если хотите

public class AccessDeniedAuthorizeAttribute : AuthorizeAttribute
{
    public string AccessDeniedViewName { get; set; }

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

        if (filterContext.HttpContext.User.Identity.IsAuthenticated &&
            filterContext.Result is HttpUnauthorizedResult)
        {
            if (string.IsNullOrWhiteSpace(AccessDeniedViewName))
                AccessDeniedViewName = "~/Account/AccessDenied";

            var requestUrl = filterContext.HttpContext.Request.Url;

            filterContext.Result = new RedirectResult(String.Format("{0}?RequestUrl={1}", AccessDeniedViewName, requestUrl));
        }
    }
}