将这样的内容添加到您的 web.config:
<customErrors mode="On" defaultRedirect="~/Login">
<error statusCode="401" redirect="~/Unauthorized" />
<error statusCode="404" redirect="~/PageNotFound" />
</customErrors>
您显然应该创建/PageNotFound 和/Unauthorized 路由、操作和视图。
编辑:对不起,我显然没有彻底理解这个问题。
问题是当AuthorizeAttribute 过滤器被执行时,它判定用户不符合要求(他/她可能已经登录,但不是正确的角色)。因此它将响应状态代码设置为 401。这被FormsAuthentication 模块拦截,然后执行重定向。
我看到了两种选择:
禁用默认重定向。
创建您自己的IAuthorizationFilter。从 AuthorizeAttribute 派生并覆盖 HandleUnauthorizedRequest。在这种方法中,如果用户通过了身份验证,请执行 redirect 到 /Unauthorized
我也不喜欢:defaultRedirect 功能很好,而不是你想自己实现的东西。第二种方法会为用户提供视觉上正确的“您未获得授权”页面,但 HTTP 状态代码将不是所需的 401。
我对 HttpModules 的了解还不够,无法说明这是否可以通过可容忍的 hack 来规避。
编辑 2:
如何通过以下方式实现您自己的 IAuthorizationFilter:从 CodePlex 下载 MVC2 代码并“借用”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 中的私有方法。