Добавьте что-то подобное в ваш web.config:
<customErrors mode="On" defaultRedirect="~/Login">
<error statusCode="401" redirect="~/Unauthorized" />
<error statusCode="404" redirect="~/PageNotFound" />
</customErrors>
Вы, очевидно, должны создать маршруты, действия и представления /PageNotFound
и /Unauthorized
.
РЕДАКТИРОВАТЬ : Извините, я, видимо, не совсем понял проблему.
Проблема заключается в том, что при выполнении фильтра AuthorizeAttribute
он решает, что пользователь не соответствует требованиям (он / она может войти в систему, но не выполняет правильную роль). Поэтому он устанавливает код состояния ответа на 401. Он перехватывается модулем FormsAuthentication
, который затем выполняет перенаправление.
Я вижу две альтернативы:
Отключить defaultRedirect.
Создайте свой собственный IAuthorizationFilter
. Получите из AuthorizeAttribute
и переопределите HandleUnauthorizedRequest. В этом методе, если пользователь аутентифицирован, выполните перенаправление в / Unauthorized
Мне тоже не нравится: функциональность defaultRedirect хороша, а не то, что вы хотите реализовать самостоятельно. Второй подход приводит к тому, что пользователю предоставляется визуально правильная страница «Вы не авторизованы», но коды состояния HTTP не будут иметь желаемого значения 401.
Я недостаточно знаю о HttpModules, чтобы сказать, можно ли это обойти с помощью терпимого взлома.
РЕДАКТИРОВАТЬ 2 :
Как насчет реализации собственного IAuthorizationFilter следующим образом: загрузите код MVC2 из CodePlex и заимствуйте код для AuthorizeAttribute. Измените метод OnAuthorization, чтобы он выглядел как
public virtual void OnAuthorization(AuthorizationContext filterContext)
{
if (AuthorizeCore(filterContext.HttpContext))
{
HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
cachePolicy.SetProxyMaxAge(new TimeSpan(0));
cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */);
}
// Is user logged in?
else if(filterContext.HttpContext.User.Identity.IsAuthenticated)
{
// Redirect to custom Unauthorized page
filterContext.Result = new RedirectResult(unauthorizedUrl);
}
else {
// Handle in the usual way
HandleUnauthorizedRequest(filterContext);
}
}
, где unauthorizedUrl
- это либо свойство фильтра, либо чтение из Web.config.
Вы также можете наследовать от AuthorizeAttribute и переопределять OnAuthorization
, но в итоге вы напишете пару приватных методов, которые уже есть в AuthorizeAttribute.