ASP.NET MVC перенаправляет на страницу с запретом доступа с помощью поставщика настраиваемых ролей
Я создаю пользовательский поставщик роли, и я устанавливаю атрибут Authorize, определяющий роль в моем контроллере, и он работает нормально, например:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
Но когда пользователь не имеет доступа к этому контроллеру, он перенаправляется на страницу входа.
Как я могу перенаправить его на страницу "AcessDenied.aspx"?
Ответы
Ответ 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));
}
}
}