Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Caching of Attributes in ASP.NET MVC, force Attribute Execution every time an Action is Executed

According to various articles (e.g. here and here) attribute results on ASP.NET MVC Actions may be cached and not executed again when a controller action is called.

That behavior is not desired in my case (e.g. I have an authorization system based on my own attributes and IPs, role checks that need to execute every time, and other things).

How can I prevent ASP.NET MVC from caching my attributes/attribute execution results and guarantee that they are executed every time?

like image 208
Alex Avatar asked Oct 15 '22 13:10

Alex


2 Answers

Look at the source code for the AuthorizeAttribute (on Codeplex or via Reflector) to see how it goes about turning off caching for authorized pages. I refactored it into a separate method on my custom authorization attribute which derives from AuthorizeAttribute.

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

protected void SetCachePolicy( AuthorizationContext filterContext )
{
    // ** IMPORTANT **
    // 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.
    HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache;
    cachePolicy.SetProxyMaxAge( new TimeSpan( 0 ) );
    cachePolicy.AddValidationCallback( CacheValidateHandler, null /* data */);
}
like image 73
tvanfosson Avatar answered Oct 21 '22 02:10

tvanfosson


I just finished a spirited discussion with Craig Stuntz (the author of the first article you listed).

I ended up using an AuthorizeAttribute with AuthorizeCore to guarantee that authorization is called even in the event the page is cached.

like image 43
Peter J Avatar answered Oct 21 '22 02:10

Peter J