ASP.NET перенаправление MVC на страницу с запрещенным доступом с помощью пользовательского поставщика ролей
Я создаю пользовательский поставщик ролей и устанавливаю атрибут Authorize, указывающий роль в моем контроллере, и он работает просто отлично, вот так:
[Authorize(Roles="SuperAdmin")]
public class SuperAdminController : Controller
...
Но когда пользователь не имеет доступа к этому контроллеру, он перенаправляется на страницу входа в систему.
Как я могу перенаправить его на "AcessDenied.aspx" страницы?8 ответов:
[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"); } } }
Вот мое решение, основанное на ответе 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(); }
Просмотры / Учетная Запись / Отказано.cshtml: (синтаксис Razor)
@{ ViewBag.Title = "Access Denied"; } <h2>@ViewBag.Title</h2> Sorry, but you don't have access to that page.
Взгляните на tvanfosson ' s Ответ из этого очень похожего вопроса , это то, что я делаю(благодаря tvanfosson), так что теперь я просто должен сказать:
[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")] public class SuperAdminController : Controller ...
Если пользователь не входит в роль, он получит представление thew, указанное в поле ViewName.
Небольшое улучшение в ответе Мэтта за счет исключения необходимости жесткого кода страницы входа в систему и необязательной установки представления "отказано в доступе" в атрибуте:
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); } } }
Перенаправление не всегда является лучшим решением
Используйте стандартный http-код 403:
return new HttpStatusCodeResult(HttpStatusCode.Forbidden);
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"); } } }
Я построил ответ Вика, чтобы у меня была отдельная страница запрещенного доступа для каждой из областей приложения. Сделал это, вернув вместо этого
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 })); } } }
Только небольшое обновление для Vic Alcazar, Добавлены детали запроса 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)); } } }