当用户不在授权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
路由,操作和视图。
编辑 :对不起,我显然没有彻底明白这个问题。
问题是,当执行AuthorizeAttribute
filter时,它决定用户不符合要求(他/她可能已经login,但不是正确的angular色)。 因此,它将响应状态码设置为401.这由FormsAuthentication
模块拦截,然后模块将执行redirect。
我看到两个select:
-
禁用defaultRedirect。
-
创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中的私有方法。
你可以用两种方法做到这一点:
-
指定错误HandleError属性,并给出一个应该显示的视图:
[HandleError(ExceptionType = typeof(UnAuthorizedException),View =“UnauthorizedError”)]
您可以指定几个不同的ExceptionTypes和视图
- 创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); } } }