owinhttp-status-code-403authorize-attributeazureportalrole-base-authorization

Azure portal. Mvc. Redirect to custom error page doesn't work for 403 error


I have configured owin role-based authorization in my MVC application. Then, I need to add a custom handling of 403 http error

I know two approaches to do it:

  1. Web.config settings:

    <customErrors mode="Off" defaultRedirect="~/Error/" redirectMode="ResponseRedirect">
     <error statusCode="403" redirect="~/Error/NoAccess" />
    </customErrors>
    
  2. Configuration inside of overridden HandleUnauthorizedRequest method in Authorize attribute:

    if (filterContext.HttpContext.User?.Identity.IsAuthenticated ?? false)
    {
       filterContext.Result = new RedirectToRouteResult(
       new RouteValueDictionary
       {
         {"action", "NoAccess"},
         {"controller", "Error"}
       });
       //I've tried two variants of below: with below line as well as without it 
       filterContext.Result.ExecuteResult(filterContext.Controller.ControllerContext);
    }
    

Both of these methods work well in my local machine when I try to get access to resources which is not allowed for my user and I see my custom page for 403 error, but when I deploy my application on azure portal, I see only white page with the following text : 'You do not have permission to view this directory or page.'. As I may understand, I need to configure this behavior on azure portal as well as I configured it in my code.

Could someone advise with it?


Solution

  • I've found the answer. The problem is appeared in case if I set response code in controller method manually as shown below:

    public ActionResult NoAccess()
    {
        Response.StatusCode = 403;
        return View();
    }
    

    In case if I delete this status setup, redirection works fine. The solution is to set to true the following flag : TrySkipIisCustomErrors

     public ActionResult NoAccess()
     {
         Response.TrySkipIisCustomErrors = true;
         Response.StatusCode = 403;
    
         return View();
     }
    

    Then everything works correctly as well.