Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can someone explain this block of ASP.NET MVC code to me, please?

this is the current code in ASP.NET MVC2 (RTM) System.Web.Mvc.AuthorizeAttribute class :-

public virtual void OnAuthorization(AuthorizationContext filterContext)
{
    if (filterContext == null)
    {
        throw new ArgumentNullException("filterContext");
    }
    if (this.AuthorizeCore(filterContext.HttpContext))
    {
        HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
        cache.SetProxyMaxAge(new TimeSpan(0L));
        cache.AddValidationCallback(
            new HttpCacheValidateHandler(this.CacheValidateHandler), null);
    }
    else
    {
        filterContext.Result = new HttpUnauthorizedResult();
    }
}

so if i'm 'authorized' then do some caching stuff, otherwise throw a 401 Unauthorized response.

Question: What does those 3 caching lines do?

cheers :)

like image 324
Pure.Krome Avatar asked Jun 06 '10 03:06

Pure.Krome


People also ask

What is MVC in ASP.NET with example?

Model View Controller (MVC) MVC is a design pattern used to decouple user-interface (view), data (model), and application logic (controller). This pattern helps to achieve separation of concerns.

Can you please explain the request flow in the ASP.NET MVC framework?

The Request flow is as follows: -Request is being taken from User to controller. -Controller processes the request from the user and creates a data Model of that particular request. -Data model that is being created is then passed to View that handles the frontend or the design.

How can I see details in MVC?

Open your MVC project in Visual Studio. Add a view model for products. Add a new controller with an action that handles displaying the product detail page.


2 Answers

This code exists to allow you to put both [OutputCache] and [Authorize] together on an action without running the risk of having a response that was generated for an authorized user cached and served to a user that is not authorized.

Here's the source code comment from AuthorizeAttribute.cs:

Since we're performing authorization at the action level, the authorization code runs after the output caching module. In the worst case this could allow an authorized user to cause the page to be cached, then an unauthorized user would later be served the cached page. We work around this by telling proxies not to cache the sensitive page, then we hook our custom authorization code into the caching mechanism so that we have the final say on whether a page should be served from the cache.

So just what is this attribute doing? It first disables proxy caching of this response, as proxies can't make the proper determination of which users are or are not authorized to view it. And if a proxy serves the response to an unauthorized user, this is a Very Bad Thing.

Now what about AddValidationCallback? In ASP.NET, the output caching module hooks events that run before the HTTP handler. Since MVC is really just a special HTTP handler, this means that if the output caching module detects that this response has already been cached, the module will just serve the response directly from cache without going through the MVC pipeline at all. This is also potentially a Very Bad Thing if the output cache serves the response to an unauthorized user.

Now take a closer look at CacheValidateHandler:

private void CacheValidateHandler(HttpContext context, object data, ref HttpValidationStatus validationStatus) {
    validationStatus = OnCacheAuthorization(new HttpContextWrapper(context));
}

// This method must be thread-safe since it is called by the caching module.
protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext) {
    if (httpContext == null) {
        throw new ArgumentNullException("httpContext");
    }

    bool isAuthorized = AuthorizeCore(httpContext);
    return (isAuthorized) ? HttpValidationStatus.Valid : HttpValidationStatus.IgnoreThisRequest;
}

This effectively just associates the AuthorizeCore method with the cached response. When the output cache module detects a match, it will re-run the AuthorizeCore method to make sure that the current user really is allowed to see the cached response. If AuthorizeCore returns true, it's treated as a cache hit (HttpValidationStatus.Valid), and the response is served from cache without going through the MVC pipeline. If AuthorizeCore returns false, it's treated as a cache miss (HttpValidationStatus.IgnoreThisRequest), and the MVC pipeline runs as usual to generate the response.

As an aside, since a delegate is formed to AuthorizeCore (thus capturing the particular instance of AuthorizeAttribute) and saved in a static cache, this is why all types subclassing AuthorizeAttribute must be thread-safe.

like image 180
Levi Avatar answered Oct 04 '22 10:10

Levi


call to AuthorizeCore will validate if request is authorized. If authorized, it put an AddValidationCallback in order to test if the cached output is still valid according to cache policy. If so, the cached output is sent to the client.

Regarding the 3 lines for caching; well, first at all you should understand that an output cache must be correct or as correct as possible. In order to meassure its "correctness", the system will test if it meets certain conditions (e.g. it has not been modified). This is stuff can be done in the 3 lines..

like image 34
S P Avatar answered Oct 04 '22 11:10

S P