1

I am thoroughly stumped on this one. Basically, I have an MVC page with a custom AuthorizeAttribute that throws a 403 error if a user is authenticated, but does not have appropriate access. The problem I am having is that I would like to redirect this error to a custom controller/action (/Error/Unauthorized).

I have added the following in my web.config

<httpErrors errorMode="Custom">
  <remove statusCode ="403" subStatusCode="-1"/>
  <error statusCode="403" path="/Error/Unauthorized" responseMode="ExecuteURL" />
</httpErrors>

With the above configuration, I do not see the default IIS 7.5 403 redirect. However, I also do not see anything. In IE, it tells me that the website requires you to login and chrome just shows me a blank page.

Any ideas?

Here is the custom authorization code in case that might help

    public class CustomAuthorize : AuthorizeAttribute
    {
        //Property to allow array instead of single string.
        private string[] _authorizedRoles;

        public string[] AuthorizedRoles
        {
            get { return _authorizedRoles ?? new string[0]; }
            set { _authorizedRoles = value; }
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            base.HandleUnauthorizedRequest(filterContext);
            if (filterContext.HttpContext.Request.IsAuthenticated)
            {
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                filterContext.Result = new HttpStatusCodeResult(403);
            }
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null)
                throw new ArgumentNullException("httpContext");

            if (!httpContext.User.Identity.IsAuthenticated)
                return false;

            //Check to see if any of the authorized roles fits into any assigned roles only if roles have been supplied.
            if (AuthorizedRoles.Any(httpContext.User.IsInRole))
                return true;

            return false;
        }
    }
Justin Pihony
  • 66,056
  • 18
  • 147
  • 180
  • OK, just trying to play around with some different scenarios, I added my customErrors section into the system.web section and tried this with a 404. In this case, (due to the TrySkipIisCustomErrors I assume), I found I did not even need the httpErrors section. However, if I try to add a 403, the page still does not resolve. Is this just how the browsers are interpreting the 403? Will they not allow a 403 to be redirected? – Justin Pihony Dec 22 '11 at 20:26

1 Answers1

0

OK, I am not sure if this is truly correct or not, but it fits my symptoms. http://forums.asp.net/t/1462153.aspx/1 I am not happy that I have to code the redirect, but I tried to make it at least explicit for future maintainability.

    public bool RedirectAuthenticatedButUnauthorizedUsers { get; set; }

    private String _redirectUnauthorizedUrl = String.Empty;
    public String RedirectUnauthorizedUrl
    {
        get { return _redirectUnauthorizedUrl; }
        set { _redirectUnauthorizedUrl = value.Trim(); }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);
        if (!RedirectAuthenticatedButUnauthorizedUsers || !filterContext.HttpContext.Request.IsAuthenticated)
            return;
        if(RedirectUnauthorizedUrl == String.Empty)
            throw new NullReferenceException("RedirectAuthenticatedButUnauthorizedUsers " +
                                             "set to true, but no redirect URL set.");
        filterContext.HttpContext.Response.Redirect(RedirectUnauthorizedUrl);
    }
Justin Pihony
  • 66,056
  • 18
  • 147
  • 180