Question

I am wanting to override the default behavior of the [Authorize] attribute. I found this similar question but it is very old and MVC has had a few iterations since it was published.

I would prefer not to create a separate 'custom' attribute class and apply that attribute on all controllers/actions in order to just send an unauthorized request to a separate controller/action. I would like to be able to do this globally and affect all the controllers/actions that are already configured with an [Authorize] attribute.

Is this possible?

Was it helpful?

Solution

Ok. Since there isn't a way to overrride the [Authorize] attribute, globally and in place, here is how I got it done.

Create a new custom AuthorizeAttribute class in the global namespace for your application (I called mine CustomAuthorizeAttribute). I placed this class file in a folder called Extend (its where I put all my custom classes when extending the MVC framework) and made sure the namespace is the same as the root namespace for my application (this way all controllers can 'see' it).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace CustomProject
{
    public class CustomAuthorizeAttribute : AuthorizeAttribute
    {
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            System.Web.Routing.RouteValueDictionary rd;
            if (filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                rd = new System.Web.Routing.RouteValueDictionary(new { action = "NotAuthorized", controller = "Error" });
            }
            else
            {
                //user is not authenticated
                rd = new System.Web.Routing.RouteValueDictionary(new { action = "Login", controller = "Account" });
            }
            filterContext.Result = new RedirectToRouteResult(rd);
        }
    }
}

My CustomAuthorizeAttribute takes into account authenticated user scenarios and reroutes/redirects appropriately.

You then need to add the [CustomAuthorize(Roles="Admin")] (use the roles that you have configured for your application) to your controllers and/or actions that you want to scrutinize.

In addition, I created an ErrorController to handle errors and added a "NotAuthorized" action for my needs. You can certainly extend this if you like. Maybe include some logging?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace HypeKick.BankUI.Controllers
{
    public class ErrorController : Controller
    {
        //
        // GET: /Error/
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult NotAuthorized()
        {
            return View();
        }
}
}

Don't forget to create the necessary views!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top