当用户不在授权angular色中时,如何提供未经授权的页面?

我正在使用这样的Authorize属性:

 [Authorize (Roles="Admin, User")] Public ActionResult Index(int id) { // blah } 

当用户不在指定的angular色,我得到一个错误页面(资源未find)。 所以我也把HandleError属性。

 [Authorize (Roles="Admin, User"), HandleError] Public ActionResult Index(int id) { // blah } 

现在进入login页面,如果用户不在指定的angular色。

当用户不符合要求的angular色之一时,我如何才能将其转到未经授权的页面而不是login页面? 如果发生不同的错误,我怎么区分这个错误和未经授权的错误,并以不同的方式处理?

添加这样的东西到你的web.config:

 <customErrors mode="On" defaultRedirect="~/Login"> <error statusCode="401" redirect="~/Unauthorized" /> <error statusCode="404" redirect="~/PageNotFound" /> </customErrors> 

你显然应该创build/PageNotFound/Unauthorized路由,操作和视图。

编辑 :对不起,我显然没有彻底明白这个问题。

问题是,当执行AuthorizeAttributefilter时,它决定用户不符合要求(他/她可能已经login,但不是正确的angular色)。 因此,它将响应状态码设置为401.这由FormsAuthentication模块拦截,然后模块将执行redirect。

我看到两个select:

  1. 禁用defaultRedirect。

  2. 创build你自己的IAuthorizationFilter 。 从AuthorizeAttribute派生并重写HandleUnauthorizedRequest。 在这种方法中,如果用户通过身份validation,则redirect到/未授权

我不喜欢:defaultRedirectfunction是不错的,而不是你想要实现自己的东西。 第二种方法导致用户被视为正确的“你没有被授权”页面,但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是filter上的属性或从Web.config读取。

你也可以从AuthorizeAttributeinheritance并重写OnAuthorization ,但是最终你会写一些已经在AuthorizeAttribute中的私有方法。

你可以用两种方法做到这一点:

  1. 指定错误HandleError属性,并给出一个应该显示的视图:

    [HandleError(ExceptionType = typeof(UnAuthorizedException),View =“UnauthorizedError”)]

您可以指定几个不同的ExceptionTypes和视图

  1. 创build一个自定义的ActionFilter,检查那里的凭据,并redirect到一个控制器,如果用户未经授权: http ://web.archive.org/web/20090322055514/http: //msdn.microsoft.com/en-us/库/ dd381609.aspx

也许根据你的问题,403状态码是更合适的(用户被识别,但是他们的账户没有足够的特权)。 401是用于你不知道用户拥有什么特权的情况。

HttpUnauthorizedResult (这是作为AuthorizeAtrribute reuslt)只是将StatusCode设置为401.因此,可能可以在IIS中设置401页面或在web.config中设置自定义错误页面。 当然,您还必须确保访问您的自定义错误页面不需要授权。

只需重写AuthorizeAttribute的HandleUnauthorizedRequest方法即可。 如果调用此方法,但用户已通过身份validation,则可以redirect到“未经授权”页面。

 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); } } }