有没有一种方法可以在Nginx中使用多个auth_request指令?

Izt*_*okK 10 authentication nginx request

我想使用多个auth_request指令来尝试与多个服务器进行身份验证-即,如果第一个身份验证服务器返回403,请尝试第二个身份验证服务器。我尝试了一个像这样的简单方法:

location /api {
    satisfy any;
    auth_request    /auth-1/;
    auth_request    /auth-2/;
    proxy_pass http://api_impl;
}

location /auth-1/ {
    internal;
    proxy_pass              http://auth_server_1;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
    proxy_set_header        X-Original-URI $request_uri;
}

location /auth-2/ {
    internal;
    proxy_pass              http://auth_server_2;
    proxy_pass_request_body off;
    proxy_set_header        Content-Length "";
    proxy_set_header        X-Original-URI $request_uri;
}
Run Code Online (Sandbox Code Playgroud)

但是nginx不会解析配置文件。我收到了回复

nginx: [emerg] "auth_request" directive is duplicate
Run Code Online (Sandbox Code Playgroud)

有没有办法在Nginx中实现这种功能?

小智 3

在谷歌中找到这个问题寻找相同的东西后,这是我的解决方案:

  • 设置将传递给环回 nginx 服务器的上游服务器
  • 让这些上游服务器执行您的 /auth-1 和 /auth-2 端点正在执行的操作,除了它们在身份验证错误时返回503(除了链中的最后一个服务器仍然返回 401 以向 nginx 发出信号,表明没有更多服务器可以尝试)
  • 告诉 nginx/auth仅使用此上游,因此它将按顺序尝试所有身份验证“服务器”(感谢 503 返回代码),直到其中一个成功或最后一个返回 401。
upstream auth {
    server 127.0.2.1:8000 max_fails=0;
    server 127.0.2.1:8001 max_fails=0;
    server 127.0.2.1:8002 max_fails=0;
}

# Method 1
server {
    listen 127.0.2.1:8000;

    location / {
        proxy_pass              http://auth_server_1; # Returns **503** on failure
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
    }
}

# Method 2
server {
    listen 127.0.2.1:8001;

    location / {
        proxy_pass              http://auth_server_2; # Returns **503** on failure
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
    }
}

# Method 3
server {
    listen 127.0.2.1:8002;

    location / {
        proxy_pass              http://auth_server_3; # Returns **401** on failure
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
        proxy_set_header        X-Original-URI $request_uri;
    }
}

server {
    # ...
    location /api {
        auth_request    /auth;
        proxy_pass http://api_impl;
    }

    location /auth {
        proxy_pass http://auth/;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URL $request_uri;
        proxy_next_upstream error timeout http_503;
    }
    # ...
}
Run Code Online (Sandbox Code Playgroud)