简体   繁体   English

Nginx 根据请求/响应值动态创建一个 map

[英]Nginx create a map dynamically based on request/response values

I am looking for a way to accomplish my below goal within the constraints of Nginx syntax.我正在寻找一种方法来在 Nginx 语法的约束下实现我的以下目标。

Scenario / Goal:场景/目标:

For various reasons, I need Nginx to validate some values that are returned from an external authentication system (further processing).由于各种原因,我需要 Nginx 来验证从外部身份验证系统返回的某些值(进一步处理)。 This seemed to be very easy to accomplish by testing the values using an Nginx map, however it doesn't appear it's as simple as I imagined.这似乎很容易通过使用 Nginx map 测试值来完成,但它似乎并不像我想象的那么简单。

The entire nginx and auth system already works fine, and I have the header values I need.整个 nginx 和 auth 系统已经工作正常,我有我需要的 header 值。

GOAL: The only thing I'm I'm trying to do is just add a map of values based on some response header data.目标:我唯一想做的就是根据一些响应 header 数据添加一个 map 的值。

Problem:问题:

Nginx map cannot be used in location/server blocks, it can only be used in http blocks. Nginx map不能用在location/server块中,只能用在http块中。

When I test the below config with nginx -t , it says:当我使用nginx -t测试以下配置时,它说:

nginx: [emerg] "map" directive is not allowed here in /etc/nginx/sites-enabled/test.conf:27 nginx:[emerg] /etc/nginx/sites-enabled/test.conf:27 中不允许使用“map”指令

I realize it's not allowed in location/server blocks but I am not sure how to create the map based on values ran within a server block.我意识到它在位置/服务器块中是不允许的,但我不确定如何根据在服务器块中运行的值创建 map。

Here is my ideal config (that does not work):这是我理想的配置(不起作用):

The ONLY thing I'm changing from the existing working config is adding the map itself and the if() statement at the bottom我从现有工作配置中唯一改变的是添加map本身和底部的if()语句

site.conf:站点配置文件:

server {
    [...]

    # Trigger an auth request
    auth_request /auth;

    # THIS VALUE MUST BE SET BEFORE MAKING THE MAP!!
    auth_request_set $auth_resp_x_auth_user $upstream_http_x_auth_user;

    location = /auth {
      # stuff omitted
    }

    # Create a map based on the result of `auth_request_set` above
    map $auth_resp_x_auth_user $is_invalid {
      default "1";
      tom "0";
      olivia "0";
      joe "0";
    }

    # stuff omitted

    location / {
     # Return 403 if the user is not valid
     if ($is_invalid) {
       return 403; 
     }
    # stuff omitted
}

Questions:问题:

  • How can I create this map of values based on my existing $auth_resp_x_auth_user ?如何根据我现有的$auth_resp_x_auth_user创建这个 map 值?
  • If it's not possible, is there any workaround way to accomplish this goal?如果不可能,是否有任何变通方法来实现此目标?

I think you're missing the key point about variables created by map : they are lazily loaded.我认为您错过了关于map创建的变量的关键点:它们是延迟加载的。 So there's nothing wrong to take your "ideal config" and simply put the map to the http {} block.因此,采用您的“理想配置”并简单地将map放入http {}块并没有错。

Indeed there's a problem with that: NGINX will check if the variable is defined during configuration parsing.确实有一个问题:NGINX 将检查变量是否在配置解析期间定义。 You can try to make a dummy definition like this:您可以尝试像这样进行虚拟定义:

http {
    map $arg_dummy $auth_resp_x_auth_user {
        default "1";
    }
    # Create a map based on the result of `auth_request_set` above
    map "$auth_resp_x_auth_user" $is_invalid {
      default "1";
      tom "0";
      olivia "0";
      joe "0";
    }
    ...
}

The dummy definition is only there to satisfy NGINX configuration check stage.虚拟定义仅用于满足 NGINX 配置检查阶段。 At run-time, it should use the value you set via auth_request_set .在运行时,它应该使用您通过auth_request_set设置的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM