【问题标题】:NGINX not sending headers or variables to js_content inside auth_requestNGINX 不向 auth_request 中的 js_content 发送标头或变量
【发布时间】:2022-12-21 10:12:36
【问题描述】:

我最近在使用 NGINX 时遇到了一些问题。我需要构建一个 NGINX 反向代理,它在特定 NGINX 变量中获取一些信息并将其发送到授权服务器。不过,在发送到上述 AuthServer 之前,需要将其解析为 HTTP POST 请求的主体。

为了完成这最后一步,我决定编写一个 NJS 函数,它获取此信息并通过子请求将其发送到授权服务器。

然而,有一个小问题:由于 NJS 函数是在 auth_request 位置调用的,它显然无法访问 NGINX 变量。

因此,我尝试通过配置添加的一些 costum 标头(在 auth_request 位置内部和外部)将变量值发送到 NJS 函数。不幸的是,这并没有解决问题。

这是我的 NGINX 配置文件:

location /operation/ {
    auth_request /authz; 
    auth_request_set $example_variable "Plz work variable";
    add_header X-Example-Header1 "Plz work header 1";
    proxy_set_header X-Example-Header2 "Plz work header 2";
    
    proxy_pass_request_headers on;
    proxy_pass http://service;
}

location /authz {
    internal;
    proxy_pass_header Authorization;
    proxy_set_header Authorization $http_authorization;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
    proxy_set_header X-Original-METHOD $request_method;
    add_header X-Example-Header3 "Plz work header 3";
    proxy_set_header X-Example-Header4 "Plz work header 4";

    proxy_pass_request_headers on; 

    js_content auth_engine.authorize_operation;
}

这是 js_content 中使用的 JS 函数的代码:

function authorize_operation(r) {

    r.log(JSON.stringify(r.headersIn));
    r.log(JSON.stringify(r.variables));
    
    // ...some code which sends data to OPA...
}

authorize_operation中的两行代码都没有打印NGINX配置应该添加的信息。具体来说,第一个 r.log 只打印初始请求的标头(而不是配置添加的标头),第二个不打印任何东西,只打印一些大括号。

有没有什么办法解决这一问题?

【问题讨论】:

    标签: nginx nginx-reverse-proxy nginx-config nginx-location njs


    【解决方案1】:

    这有点太大了,不能发表评论,所以我把它写成一个答案。

    您的 /authz 位置有不同目的指令的奇怪组合。首先,这个位置的内容处理程序将是一个 njs 函数,声明为

    js_content auth_engine.authorize_operation;
    

    因此,proxy_set_headerhttp_proxy_module 的其他指令没有任何意义。如果你不明白什么内容处理器是,阅读this ServerFault 答案的开头。请注意,您不能在单个位置混合使用两个不同的内容处理程序(js_contentproxy_pass 指令内容处理程序声明)。

    如果您想将 njs 代码与 auth_request 子请求混合,请查看 Validating OAuth 2.0 Access Tokens with NGINX and NGINX Plus 文章。您需要调用一个额外的子请求,它实际上会通过 HTTP Request njs 对象的 r.subrequest 方法向您的身份验证后端发出请求。前面提到的文章有一个很好的例子来说明如何实现这一点。

    【讨论】:

    • 嗨伊万,谢谢你的回答。在 njs 代码中,我确实向授权服务器发出了一个子请求,其结构本身与您链接的文章非常相似。无论哪种方式,问题是我无法将存储在 NGX 变量中的信息发送到 JS 代码。有什么办法吗?
    • 不确定,我没有带有 njs 模块的 nginx 实例来测试它。我更喜欢 lua-nginx-module 来编写这样的脚本。作为一个大胆的猜测,您可以尝试使用对父请求对象的 r.parent 引用来检查您会得到什么,尝试记录 r.parent.variables 代替。要了解有关子请求中 nginx 变量的更多信息,请查看 Yichun Zhang nginx 教程系列的 Variables in Subrequests 章节。
    • 这是 GitHub 上的相关discussion,也许您也能在那里找到有用的东西。
    【解决方案2】:

    您问题的第二个查询:“r.variables”不打印任何内容。

    对于在 njs(nginx js 脚本)中使用变量,指定您要查找的变量的确切名称,对我的情况有所帮助。 例如,尝试访问 Request-URI:

    var uri = r.variables.request_uri

    【讨论】:

      猜你喜欢
      • 2020-07-14
      • 2013-10-22
      • 2018-03-08
      • 2020-07-18
      • 1970-01-01
      • 2021-02-22
      • 2012-03-16
      • 2018-06-12
      • 1970-01-01
      相关资源
      最近更新 更多