Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Отдача статики в Nginx с проверкой каждого запроса  (Прочитано 13981 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« : 18-11-2015 19:10 » new

Как отдать статичный файл и при этом проверить, имеет ли данный запрос на это право.

В Ngnix есть модуль http_auth_request, с помощью которого можно прозрачно авторизовать любой запрос, в том числе к статике. Применение может быть разнообразное. Например, можно будет дать кому-либо URL и ограничить срок его годности на 5 минут.

Код:
server {
    listen: 80;
    server_name static.example.com;

    root /var/www/static;

    location / {
        auth_request /auth_static_files;
    }

    location /auth_static_files {
        internal;
        proxy_pass http://auth.example.com/check;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "0";
        proxy_set_header X-Original-URI $request_uri;
    }

Сервис auth.example.com/check получит X-Original-URI, примет решение и ответит 403 или 200. На что Ngnix либо тоже скажет 403, либо попробует отдать запрошенный файл. Из сервиса можно даже вернуть какие-либо данные в виде строк заголовка и потом добавить их в заголовок исходного запроса.

Данные для авторизации я решил передавать прямо в оригинальном запросе в зашифрованном виде. По первоначальной задумке сервис авторизации должен был выдать реальное имя файла, которое я подставлю через rewrite. Примеру:
Исходный URI: /GHFGHghjHGhjghjHJGhjty78TYUYFGUYfTYFghfgh=
Итоговый URI: /some_file.txt

К сожалению, лог уровня debug показал, что Nginx сперва выполняет rewrite и только потом выполняет авторизацию. Т.е. имя файла все равно нужно указать в строке. Получается:
Исходный URI: /some_file.txt?GHFGHghjHGhjghjHJGhjty78TYUYFGUYfTYFghfgh=
Итоговый URI: /some_file.txt

Вопрос: кто-нибудь еще этим вопросом интересовался? Получилось ли не подставлять имя файла в исходный URI?
« Последнее редактирование: 18-11-2015 21:34 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 18-11-2015 21:32 » 

Нашел такой вариант.

Код:
    location / {
        auth_request /auth;
        auth_request_set $location $upstream_http_location;
        error_page 403 = /403;
        ...
    }

    location /403 {
        if ($location) {
            return 302 $location;
        }

        return 403;
    }

    location /auth {
        ...
    }

Он плох тем, что отсылается 302 и реальный URI файла.
« Последнее редактирование: 18-11-2015 21:33 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 18-11-2015 21:41 » 

Цитата
что Nginx сперва выполняет rewrite и только потом выполняет авторизацию.
Не совсем понятно


Ты пришел
с  /GHFGHghjHGhjghjHJGhjty78TYUYFGUYfTYFghfgh=
хочешь получить
 some_file.txt (без слеша по этому uri)

Так сначала - реврайт,  а потом проверка прав

Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 18-11-2015 22:00 » 

Получилось!
Как обычно, через  Ж

Код:
server {
    listen: 80;
    server_name static.example.com;

    root /var/www/static;

    location / {
        auth_request /auth_static_files;
        auth_request_set $file $upstream_http_x_file;
        auth_request_set $error $upstream_http_x_error;
        error_page 403 =200 /rewrite_static_files;
    }

    location /auth_static_files {
        internal;
        proxy_pass http://auth.example.com/check;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "0";
        proxy_set_header X-Original-URI $request_uri;
    }

    location /rewrite_static_files {
        internal;

        if ($error) {
            return 403;
        }

        rewrite ^(.*)$ /files/$file break;
    }

Сервис авторизации в обеих случаях выдает 403, но разные заголовки: X-File при успехе и X-Error при ошибке. Локейшн /rewrite_static_files разруливает ошибки и рерайтит URI.
« Последнее редактирование: 19-11-2015 06:57 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 18-11-2015 22:03 » 

Цитата
что Nginx сперва выполняет rewrite и только потом выполняет авторизацию.
Не совсем понятно

Ты пришел
с  /GHFGHghjHGhjghjHJGhjty78TYUYFGUYfTYFghfgh=
хочешь получить
 some_file.txt (без слеша по этому uri)

Так сначала - реврайт,  а потом проверка прав

Да, сперва выполняется rewrite, потом проверка прав. А мне нужно сделать rewrite после. Выше решение без 302 наружу.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 19-11-2015 18:07 » 

Оказалось, есть способ проще: https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines