Назад | Перейти на главную страницу

Несогласованное поведение с auth_request_set и more_set_input_headers Nginx

Я пытаюсь использовать auth_request модуль в сочетании с more_set_input_headers для автоматического входа моих пользователей в веб-приложения.

В основном это работает так:

  1. У пользователей есть файлы cookie сеанса, которые их аутентифицируют.
  2. У меня есть сценарий PHP (auth.php), который проверяет файл cookie и возвращает правильное имя пользователя в качестве заголовка ответа.
  3. Nginx вызывает auth.php с auth_request и устанавливает имя пользователя в переменной.
  4. Затем Nginx вызывает веб-приложение с правильным именем пользователя в заголовке запроса.
  5. Веб-приложение считывает заголовок и регистрирует пользователя.

Это работает, но странно непоследовательно. Проблема в том, что когда пользователь обращается к веб-приложению в / app /, оно работает, но когда приложение обращается в /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"]);

Ответ при выполнении запроса GET к / app /:

Nginx supplied header value: myusername

Ответ при выполнении запроса GET к /app/index.php:

No header was supplied by nginx.

Кто-нибудь знает, что здесь происходит?

Я использую Debian Wheezy с пакетом nginx-extras от DotDeb (1.6.0-1 ~ dotdeb.1).

(небольшое примечание: при замене 'more_set_input_headers' X-Test-Header: $ auth_header ';' на 'more_set_input_headers' X-Test-Header: foobar ';' веб-приложение всегда получает заголовок)

Такое поведение, вероятно, связано с тем, что 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.