ASP.NET MVC user friendly 401 error

Viewed 14859

I have implemented errors handling in ASP.NET MVC site in a way like suggests this post.

With 404 errors all works fine. But how correctly show user friendly screen for a 401 error? They usually do not throw Exception that can be handled inside Application_Error() but rather action returns HttpUnauthorizedResult. One possible way is to add following code to the end of Application_EndRequest() method

if (Context.Response.StatusCode == 401)
{
    throw new HttpException(401, "You are not authorised");
    // or UserFriendlyErrorRedirect(new HttpException(401, "You are not authorised")), witout exception
}

But inside Application_EndRequest() Context.Session == null, errorController.Execute() fails because it cannot use default TempDataProvider.

  // Call target Controller and pass the routeData.
  IController errorController = new ErrorController();
  errorController.Execute(new RequestContext(    
       new HttpContextWrapper(Context), routeData)); // Additional information: The SessionStateTempDataProvider requires SessionState to be enabled.

So, can you suggest some best practices how to 'user friendly handle' 401 in ASP.NET MVC application?

Thanks.

4 Answers

I managed to solve this in a very simple way. I wanted to show a custom page for logged-in users ("you have no permission bla bla...") and redirect unauthenticated users to the login page (the default behaviour). So I implemented a custom AuthorizeAttribute (say CustomAuthorizeAttribute) with the HandleUnauthorizedRequest method overwritten in a way that if the user is authenticated I set the Result property of the filterContext argument with a ViewResult (in the Shared folder) called AccessDenied.aspx

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
    {
        base.HandleUnauthorizedRequest(filterContext);
    }
    else
    {
        filterContext.Result = new ViewResult { ViewName = "AccessDenied" };
    }
}

Then you have to use this new attribute instead. Regards.

Related