【问题标题】:Conditionally removing authorization header in Varnish Edge-side includes (ESI)有条件地删除 Varnish Edge-side 中的授权标头包含 (ESI)
【发布时间】:2021-12-16 12:23:43
【问题描述】:

我正在将 varnish 与 Edge-side include 一起用于主要端点需要授权的端点,但 ESI 通常不需要......但有时它们会这样做。当我希望所有 ESI 请求都保留授权标头时,我现在通过向主 request 添加一个我称为 Keep-Authorization 的标头来处理它。然后我有

vcl_recv {
  ...
  if (req.esi_level > 0 && !req.http.Keep-Authorization) {
    unset req.http.authorization;
  ...
  }
}

这工作正常,但很不优雅——它要求请求者知道是否添加该 Keep-Authorization 标头。虽然 API 目前仅供我们使用,但情况可能会发生变化。

事实上,0 级响应知道它的 ESI 子节点是否需要授权,并且应该能够设置一个标头来表明这一点。如果我可以在清漆生命周期的适当部分读取它,我可以在基于从 0 级响应得到的内容解析 ESI 之前适当地删除(或不删除)授权标头。

这似乎是我在vcl_backend_response 中必须做的事情,但我不太确定。或者,如果在 vcl_recv 中有类似 req_top 的顶级响应(在解决 ESI 时应该可用),也可以解决问题。

简而言之,我希望源能够确定是否保留授权标头以在其响应中解析 ESI。这可行吗?

【问题讨论】:

    标签: varnish varnish-vcl edge-side-includes


    【解决方案1】:

    不幸的是,没有 beresp_top 这样的东西。由于客户端逻辑和后端逻辑在 VCL 中分离,因此可以使用本机 VCL 在 vcl_recv 中获取这些信息。

    一个可能的解决方案是利用vmod_var。这是一个开源 Varnish 模块,是 https://github.com/varnish/varnish-modules 的一部分。

    目前没有它的包,所以你必须从源代码编译它。根据 Varnish 的版本,需要下载正确的分支。

    var.global_set() 函数允许您在vcl_backend_response 中设置一个全局变量,您可以使用var.global_get()vcl_recv 中检索该变量

    然后您可以使用以下 VCL 代码有条件地去除 Authorization 标头:

    vcl 4.1;
    
    import var;
    
    sub vcl_recv {
        if(var.global_get(req.url + "-remove-auth") == "true" || var.global_get(req_top.url + "-remove-auth") == "true") {
            unset req.http.Authorization;
        }
    }
    
    sub vcl_backend_response {
        if(beresp.http.X-Remove-Auth) {
            var.global_set(bereq.url + "-remove-auth", "true");
        }
    }
    

    【讨论】:

    • 谢谢!这是一个创造性的解决方案,我可以看到它是如何工作的(我们已经编译了 varnish-modules,所以这没问题),但我想将所有这些变量作为全局变量来跟踪会很麻烦。如果它涉及很多端点(并且我们有很多端点),我会觉得将所有这些变量放入某个全局内存空间中会感到不舒服。如果没有人有更好的解决方案,我会在几天后将其标记为已解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多