Search code examples
c#asp.net-mvc-5asp.net-identity-2

How to show Access Denied instead of redirecting to login page?


I'm using ASP.NET Identity 2 in an ASP.NET MVC 5 application with OWIN. As of now, if an authenticated user tries to access an action he does not have a role for, he's redirected to the login page. How can I make it so authenticated users get an AccessDenied page in that case, but unauthenticated users still get sent to login page?

ConfigureAuth method as follows:

public void ConfigureAuth(IAppBuilder app)
{
    app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
    app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    app.UseCookieAuthentication(new CookieAuthenticationOptions
    {
        AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
        LoginPath = new PathString("/Account/Login"),
        Provider = new CookieAuthenticationProvider
        {
        }
    });
    app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    app.UseSaml2Authentication(GetSamlOptions());
}


Solution

  • I implemented a custom authorization attribute as follows:

    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public sealed class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
            if (filterContext.Result is HttpUnauthorizedResult)
            {
                var route_values = new RouteValueDictionary
                {
                    ["controller"] = "Account"
                };
                if (filterContext.HttpContext.User.Identity.IsAuthenticated)
                {
                    route_values["action"] = "AccessDenied";
                }
                else
                {
                    route_values["action"] = "Login";
                    route_values["returnUrl"] = filterContext.HttpContext.Request.Url.PathAndQuery;
                }
                filterContext.Result = new RedirectToRouteResult(route_values);
            }
        }
    }
    

    I'm still open to any answer that leverages some OWIN configuration value.

    Thanks to everyone that helped.