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

走远了吗. 提交于 2019-11-29 14:55:44

问题


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 :)


回答1:


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.




回答2:


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..



来源:https://stackoverflow.com/questions/2983030/can-someone-explain-this-block-of-asp-net-mvc-code-to-me-please

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!