How do I serve up an Unauthorized page when a user is not in the Authorized Roles?

前端 未结 5 769
眼角桃花
眼角桃花 2020-12-04 15:54

I am using the Authorize attribute like this:

[Authorize (Roles=\"Admin, User\")]
Public ActionResult Index(int id)
{
    // blah
}
5条回答
  •  无人及你
    2020-12-04 16:16

    Add something like this to your web.config:

    
         
         
    
    

    You should obviously create the /PageNotFound and /Unauthorized routes, actions and views.

    EDIT: I'm sorry, I apparently didn't understand the problem thoroughly.

    The problem is that when the AuthorizeAttribute filter is executed, it decides that the user does not fit the requirements (he/she may be logged in, but is not in a correct role). It therefore sets the response status code to 401. This is intercepted by the FormsAuthentication module which will then perform the redirect.

    I see two alternatives:

    1. Disable the defaultRedirect.

    2. Create your own IAuthorizationFilter. Derive from AuthorizeAttribute and override HandleUnauthorizedRequest. In this method, if the user is authenticated do a redirect to /Unauthorized

    I don't like either: the defaultRedirect functionality is nice and not something you want to implement yourself. The second approach results in the user being served a visually correct "You are not authorized"-page, but the HTTP status codes will not be the desired 401.

    I don't know enough about HttpModules to say whether this can be circumvented with a a tolerable hack.

    EDIT 2: How about implementing your own IAuthorizationFilter in the following way: download the MVC2 code from CodePlex and "borrow" the code for AuthorizeAttribute. Change the OnAuthorization method to look like

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

    where unauthorizedUrl is either a property on the filter or read from Web.config.

    You could also inherit from AuthorizeAttribute and override OnAuthorization, but you would end up writing a couple of private methods which are already in AuthorizeAttribute.

提交回复
热议问题