代码之家  ›  专栏  ›  技术社区  ›  Pure.Krome

有人能给我解释一下这段ASP.NETMVC代码吗?

  •  5
  • Pure.Krome  · 技术社区  · 14 年前

    这是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未经授权的响应。

    问题: 这三条缓存线是做什么的?

    2 回复  |  直到 14 年前
        1
  •  15
  •   Levi    14 年前

    此代码允许您将[OutputCache]和[Authorize]放在一个操作上,而不必冒着为授权用户生成的响应被缓存并提供给未授权用户的风险。

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

    因为我们在执行授权 代码在输出缓存之后运行 模块。最坏的情况可能是 允许授权用户导致 要缓存的页,然后 未经授权的用户稍后将 自定义授权码 缓存机制,以便 最后决定一页是否应该

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

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

    现在仔细看看 缓存验证句柄 :

    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(从而捕获AuthorizeAttribute的特定实例)并保存在静态缓存中,这就是为什么所有子类化AuthorizeAttribute的类型都必须是线程安全的。

        2
  •  2
  •   S P    14 年前

    调用AuthorizeCore将验证请求是否被授权。

    关于缓存的3行;