Я не уверен, что «стандартные» подходы для решения этой проблемы. Тем не менее, это простой метод для сред с небольшим количеством пользователей, которые не включают sudo
и не изменяют UID внутри веб-сервера (это может быть очень проблематичным для одновременного доступа нескольких пользователей. пользователей).
Запустить процесс демона для каждого пользователя, имеющего доступ к этому приложению. Этот процесс должен сам обслуживать веб-запросы для этого пользователя через FastCGI (заменять протокол по вашему выбору). У вашего веб-сервера должно быть какое-то сопоставление пользователя с номером порта. Затем перенаправьте запросы вашего шлюза на соответствующий процесс FastCGI на основе входа в систему, используемого пользователем Django.
Пример (использование перенаправлений internal
по NGINX, при условии установки с FastCGI):
- Пользователь
foo
входит в веб-приложение Django
- Страница запросов пользователя
/.../
- Приложение Django получает запрос на
/.../
от пользователя foo
- Приложение Django возвращает настраиваемый заголовок HTTP
X-Accel-Redirect
, чтобы указать внутреннее перенаправление на /delegate/foo/.../
.
- NGINX forwards находит местоположение
/delegate/foo/
, связанное с обработчиком FastCGI на порту 9000
- Обработчик FastCGI работает от имени пользователя
foo
и предоставляет доступ к содержимому в домашнем каталоге.
Вы можете заменить веб-сервер и протокол связи на комбинации по вашему выбору. Я использовал FastCGI здесь, потому что он позволяет писать и шлюз и обработчик как приложения Django. Я выбрал NGINX из-за функции перенаправления internal
. Это предотвращает олицетворение путем прямого использования /delegate/foo/.../
URL-адресов пользователями, отличными от foo
.
Обновление
Пример:
Если у вас есть модуль flup
, вы можете запустить сервер FastCGI напрямую с помощью Django. Чтобы запустить приложение Django через FastCGI под определенной учетной записью пользователя, вы можете использовать:
sudo -u $user python /absolute/path/to/manage.py runfcgi host=127.0.0.1 port=$port
Замените $user
на имя пользователя и $port
на уникальный порт для этого пользователя (два пользователя не могут использовать один и тот же порт).
Предполагая конфигурацию NGINX, вы можете настроить ее следующим образом:
location /user/$user {
internal;
fastcgi_pass 127.0.0.1:$port;
# additional FastCGI configuration...
}
Обязательно добавьте одну такую директиву для каждой комбинации $user
и $port
выше.
Затем, из вашего внешнего приложения Django, вы можете проверить разрешения и прочее, используя:
@login_required
def central_dispatch_view ( request ):
response = HttpResponse()
response['X-Accel-Redirect'] = '/user/'+request.user.username
return response
Отказ от ответственности: Это полностью не проверено, и спустя почти год после первоначального ответа, я не уверен, что это возможно, главным образом потому, что документация по XSendFile в NGINX указывает, что это должно работать с статическими файлами . Я больше не спрашивал, можно ли на самом деле выполнить внутреннее перенаправление NGINX из приложения FastCGI.
Альтернативный раствор:
Лучший подход может включать не внутренние перенаправления, а использование авторизатора FastCGI. По сути, FastCGI - это программа, которую ваш веб-сервер запускает перед обработкой запроса. Затем вы можете обойти теневое внутреннее перенаправление и просто иметь авторизатор FastCGI, который проверяет, действительно ли запрос на доступ к /user/foo/
может быть получен от пользователя Django, вошедшего в систему как foo
. Эта программа-авторизатор не сможет работать как приложение Django (поскольку это не цикл HTTP-запроса / ответа), но вы можете написать его, используя flup
и получить доступ к настройкам Django.