2

I've got some custom FormsAuthentication with a custom AuthorizeAttribute where I'm maintaining the cookie manually, but I'm doing it within the filter's context.

What I want to do is move this to the very beginning entry point, at the very beginning of the request's life, and only do it once, and not rely on an attribute kicking it off.

But, I don't know where that would be. MVC's page lifecycle is very different than the WebForms lifecycle, so its not as cut and dry as subscribing to one of WebForm's page lifecycle events.

So in ASP.NET MVC, where does the HttpContext begin?

2

2 Answers 2

5

Update:

With more digging into this I came across Cephas Lin's excellent article and PDF of ASP.NET MVC 5's lifecycle.

The PDF contains two images that clearly portray the flow of the MVC 5's lifecycle. The first gives a 10,000 foot perspective of it all. The second image is very detailed and much too large to share here.

The first image:

enter image description here

My workaround:

After doing some digging I've pieced together somewhat of a workaround. Two Authorization filters that are executed in different orders.

MVC filters have an order of operation based on Eranga's answer to this question: https://stackoverflow.com/questions/6561883/in-what-order-are-filters-executed-in-asp-net-mvc

Eranga wrote:

Filters run in the following order:

  1. Authorization filters
  2. Action filters
  3. Response filters
  4. Exception filters

For example, authorization filters run first and exception filters run last. Within each filter type, the Order value specifies the run order. Within each filter type and order, the Scope enumeration value specifies the order for filters. This enumeration defines the following filter scope values (in the order in which they run):

  1. First
  2. Global
  3. Controller
  4. Action
  5. Last

Extracted from MSDN

With this knowledge, I've implemented a second Authorization attribute LoadAuthCookie which handles loading the cookie, fetching the current user's relevant role/permission data into a custom IPrincipal and IIdentity, and assigning the current HttpContext's user to this IPrincipal.

The LoadAuthCookie attribute only loads the cookie data if it exists and does not handle redirection or any other Authorization logic, and is registered within RegisterGlobalFilters.

Starting from Global.asax:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        /* other global stuff */
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        /* other global stuff */
    }
}

And then

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new LoadAuthCookie());
}

This registers LoadAuthCookie attribute not only before, but also at a higher order of operation than the other Authorization attributes.

Then my other Authorization attribute, CustomAuthorize, can be applied at the Controller/Action level, and always fires after the auth cookie has been loaded, so has access to all of the nice things in the custom IPrincipal.

[CustomAuthorize(Role=Role.Admin)]
public class AdminController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}

However this probably isn't ideal, and a custom Authentication filter will be the place to load the auth cookie, instead of a custom Authorization filter. Authentication happens before Authorization.

0

If this were recommended, there would be no AuthorizeAttribute and it wouldn't be an unsealed class.

Even if you could mess with it--and you can't--the worst performance hit is the fact that each HttpContext takes up a lot of memory. Checking if an item exists in the session dictionary is a drop in a bucket for the current version of ASP.NET.

Self hosted NancyFX and ASP.NET MVC 6 actually tackled some of these challenges. Both free of using the HttpContext if you choose to not host on IIS. You may find NancyFX's pipelines and lack of HTTPContext more agreeable and performant than what you're doing in ASP.NET.

1
  • I don't understand brian, are you saying that there is no centralized HttpContext entry point? Mar 18, 2015 at 14:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.