我遇到了这个奇怪的错误:
我在 8090 中运行一个 Jenkins 服务,我想通过带有 proxy_pass 的 Nginx auth_basic 对其进行密码保护。当不使用 auth_basic 执行代理传递时,我可以毫无问题地访问该站点:
server {
listen 8080;
location / {
proxy_pass http://localhost:8090;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering off;
proxy_pass_header Authorization;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# auth_basic "Restricted"; #For Basic Auth
# auth_basic_user_file /etc/nginx/htpasswd; #For Basic Auth
}
}
但是,当取消注释这两行 auth 时,我会在浏览器中看到预期的登录页面。如果我输入了无效的凭据,我会在 nginx/error.log 中收到预期的错误:
(错误用户)
2014/07/30 18:59:58 [错误] 15374#0:*1 在“/etc/nginx/htpasswd”中未找到用户“afds”,客户端:xx.xx.xx.xx,服务器:example.com,请求:“GET /job/xyz HTTP/1.1”,主机:“example.com:8080”
(好用户,密码错误)
2014/07/30 19:01:43 [错误] 15374#0:*44 用户“jenkins”:密码不匹配,客户端:xx.xx.xx.xx,服务器:example.com,请求:“GET /job/xyz HTTP/1.1”,主机:“example.com:8080”
但是,如果我输入正确的用户/密码组合,我不会在 nginx/error.log 中得到任何内容,而是在 nginx/access.log 中得到以下内容
xx.xx.xx.xx - jenkins [30/Jul/2014:19:03:53 -0500] “GET /job/xyz HTTP/1.1” 401 278 “-” “Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML,如 Gecko) Chrome/36.0.1985.125 Safari/537.36”
浏览器再次要求输入密码。
知道为什么会发生这种情况吗?
答案1
正如@Lukas 所解释的那样,将授权标头转发到后端将使您的客户端尝试对其进行身份验证。由于您可能没有在后端定义任何身份验证,因此它将以 401 响应,因为RFC 2617需要:
如果原始服务器不希望接受随请求发送的凭证,它应该返回 401(未授权)响应。
您的后端与身份验证无关,因为它是由代理完成的。不要代理该标头字段。
如果您希望后端再次验证客户端,您auth_basic
也应该在那里激活,使用相同的用户/密码数据库。管理用户时要小心,您现在需要保持 2 个副本同步...