有人可以向我解释这段 ASP.NET MVC 代码吗?

发布于 2024-09-04 05:30:26 字数 779 浏览 8 评论 0原文

这是 ASP.NET MVC2 (RTM) System.Web.Mvc.AuthorizeAttribute 类中的当前代码:-

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();
    }
}

所以如果我“授权”,则执行一些缓存操作,否则抛出 401 未经授权的响应。

问题:这 3 条缓存线有什么作用?

干杯 :)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

枉心 2024-09-11 05:30:26

此代码的存在是为了允许您将 [OutputCache] 和 [Authorize] 放在一起进行操作,而不会冒为授权用户生成的响应被缓存并提供给未经授权的用户的风险。

以下是 AuthorizeAttribute.cs 的源代码注释:

由于我们正在执行授权
在行动层面,授权
代码在输出缓存后运行
模块。在最坏的情况下,这可能
允许授权用户导致
要缓存的页面,然后是
未经授权的用户稍后将被
提供缓存页面。我们围绕
这是通过告诉代理不要缓存
敏感页面,然后我们挂钩
自定义授权码进入
缓存机制,这样我们就有了
最终决定页面是否应该
从缓存中提供。

那么这个属性到底是做什么的呢?它首先禁用此响应的代理缓存,因为代理无法正确确定哪些用户有权或无权查看它。如果代理向未经授权的用户提供响应,这是一件非常糟糕的事情。

现在 AddValidationCallback 怎么样?在 ASP.NET 中,输出缓存模块挂钩在 HTTP 处理程序之前运行的事件。由于 MVC 实际上只是一个特殊的 HTTP 处理程序,这意味着如果输出缓存模块检测到该响应已被缓存,则该模块将直接从缓存提供响应,而根本不经过 MVC 管道。如果输出缓存为未经授权的用户提供响应,这也可能是一件非常糟糕的事情。

现在仔细看看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;
}

这实际上只是将AuthorizeCore方法与缓存的响应相关联。当输出缓存模块检测到匹配时,它将重新运行 AuthorizeCore 方法以确保当前用户确实可以查看缓存的响应。如果 AuthorizeCore 返回 true,则将其视为缓存命中 (HttpValidationStatus.Valid),并且从缓存提供响应,而不通过 MVC 管道。如果 AuthorizeCore 返回 false,则将其视为缓存未命中 (HttpValidationStatus.IgnoreThisRequest),并且 MVC 管道照常运行以生成响应。

顺便说一句,由于委托是为 AuthorizeCore 形成的(从而捕获 AuthorizeAttribute 的特定实例)并保存在静态缓存中,这就是为什么所有子类化 AuthorizeAttribute 的类型都必须是线程安全的。

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.

七月上 2024-09-11 05:30:26

调用 AuthorizeCore 将验证请求是否获得授权。
如果获得授权,它会放置一个 AddValidationCallback 以便根据缓存策略测试缓存的输出是否仍然有效。如果是,则将缓存的输出发送到客户端。

关于缓存的3行;
好吧,首先您应该了解输出缓存必须正确或尽可能正确。为了衡量它的“正确性”,系统会测试它是否满足某些条件(例如没有被修改过)。
这是可以在 3 行中完成的事情..

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文