ASP.NET MVC – How to show unauthorized error on login page?

UPDATE (Jun 2015): @daniel-lidström has correctly pointed out that you should not use Response.Redirect in an ASP.NET MVC application. For more information about why, please see this link: Response.Redirect and ASP.NET MVC – Do Not Mix.

UPDATE (Sep 2014): I’m not sure when HandleUnauthorizedRequest was added to the AuthorizeAttribute, but either way I’ve been able to refine the AuthorizeRedirect code into something smaller and simpler.

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
    public string RedirectUrl = "~/Error/Unauthorized";

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        base.HandleUnauthorizedRequest(filterContext);

        if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.Result = new RedirectResult(RedirectUrl);
        }
    }
}

Original Answer Below (still fully functional)

I’ve left this answer here as it still gives you an insight as to how the Authorization pipeline works.

For anyone still landing here, I’ve edited Ben Scheirman’s answer to automatically redirect to an unauthorized page when the user is logged in but not authorized. You can change the redirect path using the name parameter RedirectUrl.

EDIT: I’ve made the solution thread-safe thanks to the advice of Tarynn and MSDN

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AuthorizeRedirect : AuthorizeAttribute
{
    private const string IS_AUTHORIZED = "isAuthorized";

    public string RedirectUrl = "~/error/unauthorized";

    protected override bool AuthorizeCore(System.Web.HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);

        httpContext.Items.Add(IS_AUTHORIZED, isAuthorized);

        return isAuthorized;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);

        var isAuthorized = filterContext.HttpContext.Items[IS_AUTHORIZED] != null 
            ? Convert.ToBoolean(filterContext.HttpContext.Items[IS_AUTHORIZED]) 
            : false;

        if (!isAuthorized && filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
        {
            filterContext.RequestContext.HttpContext.Response.Redirect(RedirectUrl);
        }
    }
}

Leave a Comment