我正在尝试使用授权请求模块与more_set_input_headers自动让我的用户登录到网络应用程序。
基本上,它的工作原理如下:
- 用户有一些用于对他们进行身份验证的会话 cookie。
- 我有一个 PHP 脚本(auth.php),用于验证 cookie 并返回其正确的用户名作为响应标头。
- Nginx 使用 auth_request 调用 auth.php,并将用户名设置在变量中。
- 然后,Nginx 使用设置为正确用户名的请求标头来调用 Web 应用程序。
- Web 应用程序读取标题,并让用户登录。
这可以工作,但奇怪的是不一致。问题是,当用户访问 /app/ 上的 Web 应用程序时,它可以工作,但当在 /app/index.php 上访问该应用程序时,它永远不会收到来自 nginx 的标头。
我创建了一个可以重现该错误的模拟配置。
Nginx 站点配置:
server {
server_name www.example.com
index index.php index.html;
# --- Internal auth
location /auth {
internal;
root /var/www/sf;
location /auth/auth.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include includes/fastcgi_params;
fastcgi_pass_request_body off;
fastcgi_param CONTENT_LENGTH 0;
}
location /auth {
deny all;
}
}
location / {
auth_request /auth/auth.php;
auth_request_set $auth_header $upstream_http_x_auth_header;
more_set_input_headers 'X-Test-Header: $auth_header';
location /app {
root /var/www/sf;
# Allow these locations
location = /app/ {
allow all;
}
location /app/index.php {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include includes/fastcgi_params;
}
# Deny everything else
location /app/ {
deny all;
}
}
}
}
/var/www/sf/auth/auth.php:
<?php
// Mock precondition checker
function is_allowed() {
return true;
}
// Set the default response code
http_response_code(403);
if(!is_allowed())
exit();
// Return our header and the OK response code
header("X-Auth-Header: myusername");
http_response_code(200);
/var/www/sf/app/index.php:
<?php
if(empty($_SERVER["HTTP_X_TEST_HEADER"]))
exit("No header was supplied by nginx.");
exit("Nginx supplied header value: ". $_SERVER["HTTP_X_TEST_HEADER"]);
对 /app/ 执行 GET 请求时的响应:
Nginx supplied header value: myusername
对 /app/index.php 执行 GET 请求时的响应:
No header was supplied by nginx.
有人知道这里发生了什么事吗?
我正在使用 Debian Wheezy 和来自 DotDeb 的 nginx-extras 包(1.6.0-1~dotdeb.1)。
(小提示:当您将 'more_set_input_headers 'X-Test-Header: $auth_header';' 替换为 'more_set_input_headers 'X-Test-Header: foobar';' 时,Web 应用程序始终会收到一个标头)
答案1
这种行为可能是因为
more_set_input_headers
处理程序是在访问阶段(auth_request
起作用的地方)之前执行的,因此只有在内部重定向时才会更改请求。
解决问题的方法是停止使用more_set_input_headers
(无论如何这都是非常错误的,请求标头不应该更改)并改用本机fastcgi_param
:
fastcgi_param HTTP_X_TEST_HEADER $auth_header;
复制自http://mailman.nginx.org/pipermail/nginx/2014-June/044281.html。