我正在使用Authorize
这样的属性:
[Authorize (Roles="Admin, User")]
Public ActionResult Index(int id)
{
// blah
}
当用户不在指定的角色中时,我会收到一个错误页面(找不到资源)。所以我也放了HandleError
属性。
[Authorize (Roles="Admin, User"), HandleError]
Public ActionResult Index(int id)
{
// blah
}
如果用户不在指定的角色,现在进入登录页面。
如果用户未满足其中一个必需的角色,如何让它转到 Unauthorized 页面而不是登录页面?如果发生不同的错误,我如何将该错误与未经授权的错误区分开来并以不同的方式处理它?</ p>
答案 0 :(得分:27)
将这样的内容添加到您的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:从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中的私有方法。
答案 1 :(得分:7)
你可以用两种方式做到这一点:
指定HandleError属性的错误,并提供应显示的视图:
[HandleError(ExceptionType = typeof(UnAuthorizedException), View =“UnauthorizedError”)]
您可以指定几种不同的ExceptionTypes和视图
答案 2 :(得分:4)
根据您的问题(可识别用户,但他们的帐户没有足够的特权),403状态代码可能更合适。 401适用于您不知道用户拥有哪些内容的情况。
答案 3 :(得分:3)
HttpUnauthorizedResult
(这是AuthorizeAtrribute
的重新发送)只是将StatusCode设置为401.因此,您可以在IIS中设置401页面或在web.config中设置自定义错误页面。当然,您还必须确保不需要授权访问自定义错误页面。
答案 4 :(得分:0)
只需覆盖AuthorizeAttribute的HandleUnauthorizedRequest方法即可。如果调用此方法,但用户已通过身份验证,则可以重定向到“未授权”页面。
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Area = "", Controller = "Error", Action = "Unauthorized" }));
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}