nginx代理认证拦截

Posted

技术标签:

【中文标题】nginx代理认证拦截【英文标题】:nginx proxy authentication intercept 【发布时间】:2017-03-19 17:26:18 【问题描述】:

我有几个服务,它们支持一个 nginx 实例。为了处理身份验证,在 nginx 中,我拦截每个请求并将其发送到身份验证服务。在那里,如果凭据正确,我将设置一个包含用户相关信息的 cookie。

现在应该将请求路由到适当的服务,并设置 cookie。

这是我的 nginx 配置:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events 
  worker_connections  1024;


http 
  upstream xyz 
    server ***;
  

  upstream auth 
    server ***;
  

  server 
   listen       8080;
   location ~ ^/(abc|xyz)/api(/.*)?$ 
     auth_request /auth-proxy;

     set $query $2;

     proxy_pass http://$1/api$query$is_args$args;
     proxy_set_header X-Target $request_uri;
     proxy_set_header Host $http_host;
   

   location = /auth-proxy 
    internal;
    proxy_pass http://auth;

    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Target $request_uri;
    proxy_set_header Host $http_host;
    proxy_set_header X-CookieName "auth";
    proxy_set_header Cookie "auth=$cookie_auth";
    proxy_set_header Set-Cookie "auth=$cookie_auth";
    proxy_cookie_path / "/; Secure; HttpOnly";
    add_header Cookie "auth=$cookie_auth";
    add_header Set-Cookie "auth=$cookie_auth";
  

如果我使用手动设置的 x-target 标头向 /auth-proxy 发出请求,则响应包含预期的 cookie。

如果我向所需目标发出请求,请求被拦截,它到达 /auth-proxy,它正确设置了 cookie。但是,当请求到达目标时,它并不包含 cookie。

我假设 nginx 在做目标请求时没有转发 cookie。

过去几天我一直在为此苦苦挣扎……我错过了什么?

谢谢!

【问题讨论】:

【参考方案1】:

我终于明白了。我使用 auth_request_set 从身份验证响应中读取 cookie,并在对调用者的响应和对目标的后续请求中手动设置它。

因为if is evil,我在lua中添加了check in。

server 
  listen       8080;
  location ~ ^/(abc|xyz)/api(/.*)?$ 
    auth_request /auth-proxy;

    # read the cookie from the auth response
    auth_request_set $cookie $upstream_cookie_auth;
    access_by_lua_block 
      if not (ngx.var.cookie == nil or ngx.var.cookie == '') then
        ngx.header['Set-Cookie'] = "auth=" .. ngx.var.cookie .. "; Path=/"
      end
    
    # add the cookie to the target request
    proxy_set_header Cookie "auth=$cookie";

    set $query $2;

    proxy_pass http://$1/api$query$is_args$args;
    proxy_set_header X-Target $request_uri;
    proxy_set_header Host $http_host;
  

【讨论】:

以上是关于nginx代理认证拦截的主要内容,如果未能解决你的问题,请参考以下文章

nginx 正向代理 配置https 双向认证

nginx+kibana代理以及简单认证

markdown Docker Nginx反向代理+密码认证+ http

使用nginx 的反向代理 给 kibana加上basic的身份认证

centos7.3给squid搭建代理服务器添加认证nginx

用nginx TCP反向代理作mail邮件代理