Как отобразить страницу пользовательских ошибок для результата Http 401?
У меня есть контроллер с атрибутом Authorize следующим образом:
[Authorize(Roles = "Viewer")]
public class HomeController : Controller
{
//...
}
и у моего web.config есть customErrors, как показано ниже:
<customErrors mode="On">
<error statusCode="401" redirect="notauthorized.html"/>
</customErrors>
Когда я пытаюсь вызвать действие на домашнем контроллере с помощью неавторизованной роли, я просто получаю пустую страницу. Я не перенаправляюсь на пользовательскую страницу.
Любые идеи?
Ответы
Ответ 1
Я понимаю, что этот вопрос немного стар, но это может помочь кому-то.
Для 401 вы, вероятно, увидите стандартную страницу 401 Unauthorized, даже если вы добавили 401 в раздел customerrors в вашем web.config. Я прочитал, что при использовании IIS и проверки подлинности Windows проверка происходит до того, как ASP.NET даже увидит запрос, поэтому вы видите пустую страницу на Cassini, а на IIS - 401.
В моем проекте я отредактировал файл Global.asax, чтобы перенаправить на маршрут, который я создал для ошибок 401, отправив пользователя в представление "Несанкционированное видеть это".
В Global.asax:
void Application_EndRequest(object sender, System.EventArgs e)
{
// If the user is not authorised to see this page or access this function, send them to the error page.
if (Response.StatusCode == 401)
{
Response.ClearContent();
Response.RedirectToRoute("ErrorHandler", (RouteTable.Routes["ErrorHandler"] as Route).Defaults);
}
}
и в Route.config:
routes.MapRoute(
"ErrorHandler",
"Error/{action}/{errMsg}",
new { controller = "Error", action = "Unauthorised", errMsg = UrlParameter.Optional }
);
и в контроллере:
public ViewResult Unauthorised()
{
//Response.StatusCode = 401; // Do not set this or else you get a redirect loop
return View();
}
Ответ 2
Посмотрите tvanfosson ответ от этот очень похожий вопрос. Это то, что я делаю (спасибо tvanfosson), так что теперь я просто должен сказать:
[MyAuthorize(Roles="SuperAdmin",ViewName="AccessDenied")]
public class SuperAdminController : Controller
...
Если пользователь не находится в роли, он получит это представление, указанное ViewName.
Примечание. пустая страница исходит от Cassini, если вы переместите приложение на реальный сервер IIS, вы увидите 401.
Ответ 3
Стандартный подход, насколько мне известно, состоит в том, чтобы иметь простой контроллер ошибок, который обрабатывает входящие запросы и выводит соответствующее представление в зависимости от того, какой код httpstatus был возвращен... что-то вроде этого:
public class ErrorController : Controller
{
[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Index()
{
//Check if the statuscode is HttpStatusCode.NotFound;
if(Response.StatusCode == 401)
return View("NotAuthorised");
return View();
}
}
а затем укажите действие перенаправления в вашем webconfig:
<customErrors mode="On" defaultRedirect="~/Error" />
Ответ 4
Также вы можете создать свой собственный настраиваемый атрибут авторизации и настроить собственный маршрут для перенаправления пользователей на свою страницу.
Вот пример моего проекта:
/*../controllers/CustomAuthorizationAttribute.cs */
public class CustomAuthorizationAttribute : FilterAttribute, IAuthorizationFilter
{
void IAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)
{
string session = filterContext.HttpContext.Session["id"] != null ? filterContext.HttpContext.Session["id"].ToString() : null;
if ( string.IsNullOrEmpty(session) )
{
// Unauthorized!
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "action", "Create" }, { "controller", "Sessions" }
//,{ "parameterName", "YourParameterValue" }
}
);
}
}
}
и вы добавляете свой "флаг" в свой контроллер действий, как этот
/*../controllers/ReportsController.cs */
public class ReportsController : Controller
{
[CustomAuthorizationAttribute]
public ActionResult Index()
{
//do something
}
}