Use nginx to add authentication to any application | okta developer

Bonus: who logged in?

If you’re putting a dynamic web app behind nginx and you care not only about whether someone was able to log in, but also who they are, there is one more trick we can use.

Configure and deploy vouch

You’ll need to download Vouch and compile the Go binary for your platform. You can follow the instructions in the project’s README file.

Creating a pkcs #12 (pfx)

Now the signed certifcate must be made installable on a device in a way that
bundles the client keys and certificate. The resultant archive is effectively
a password, so it must be kept as safe as the other private keys.

To create the pfx:

Signing a csr

A CSR must now be signed by the CA; this is the CA saying “I know this person
or device: they are who they say they are.”

Using the nginx auth_request module

Enter the nginx auth_request module.

Когда стоит использовать basic auth

По мне, ее стоит применять в двух случаях.

Первое, при разработке проекта, чтобы скрыть от посторонних глаз целый сайт или отдельный раздел.


Второе, в простой админке вроде упомянутого примера с лендингом.

Настройка и запуск сервиса аутентификации nginx-ldap-auth

Для запуска сервиса nginx-ldap-auth будем использовать docker. Для начала нужно клонировать репозиторий с сервисом с github:

Настройка контейнера nginx для авторизации в active directory (ldap)

Мы проверили работу демона аутентфикации nginx-ldap-auth, теперь можно перейти к настройке Nginx. В данной статье, покажу, как настроить авторизацию для docker registry с учетной записью Active Directory. Nginx будем запускать в docker контейнере. Создадйте Dockerfile:

FROM nginx
COPY nginx-ldap-auth.conf /etc/nginx/conf.d/nginx-ldap-auth.conf

В директории с Dockerfile создадйте файл конфигурации nginx-ldap-auth.conf. Содержание файла:

Плюсы и минусы базовой аутентификации

Из плюсов: простота и нативность реализации. Делается парой команд и обеспечивается средствами браузера.

Рецепты nginx: авторизация через есиа

Для приготовления авторизации через ЕСИА нам понадобится сам

nginx

и его плагины

encrypted-session

,

headers-more

,

auth_request

,

uuid4

,

set-misc

,

echo

,

json

,

sign

,

jwt

. (Я дал ссылки на свои форки, т.к. делал некоторые изменения, которые пока не удалось пропихнуть в оригинальные репозитории. Можно также воспользоваться

готовым образом

.)

Для начала зададим

encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";

Дальше, на всякий случай, отключаем авторизационный заголовок

more_clear_input_headers Authorization;

Теперь защищаем всё авторизацией

auth_request /auth;
location =/auth {
    internal;
    set_decode_base64 $auth_decode $cookie_auth; # раскодируем авторизационную куку
    set_decrypt_session $auth_decrypt $auth_decode; # расшифровываем авторизационную куку
    if ($auth_decrypt = "") { return 401 UNAUTHORIZED; } # если не удалось расшифровать, то значит пользователь не авторизован
    more_set_input_headers "Authorization: Basic $auth_decrypt"; # подменить авторизацию на basic (чтобы использовать переменную $remote_user)
    echo -n OK; # пользователь авторизован
}

Для авторизованных пользователей показываем контент из их папки

location / {
    alias html/$remote_user/;
}

А при отсутствии авторизации перенаправляем на ЕСИА

error_page 401 = @error401;
location @error401 {
    set $client_id мнемоника; # задаём мнемонику ЕСИА
    set $scope openid; # задаём запрашиваемые скоупы
    uuid4 $state; # генерируем случайное состояние
    set_formatted_local_time $timestamp "%Y.%m.%d %H:%M:%S %z"; # задаем дату-время в требуемом ЕСИА формате
    sign_certificate /data/nginx/esia.crt; # задаём сертификат (который мы загрузили в ЕСИА)
    sign_certificate_key /data/nginx/esia.key; # задаём приватный ключ
    sign_set $client_secret $scope$timestamp$client_id$state; # подписываем необходимые ЕСИА параметры
    set_escape_uri $access_type_escape online; # задаём необходимый ЕСИА способ доступа и кодируем его
    set_escape_uri $client_id_escape $client_id; # кодируем мнемонику
    set_escape_uri $client_secret_escape $client_secret; # кодируем подпись
    set_escape_uri $request_uri_escape $request_uri; # кодируем исходный запрос
    set_escape_uri $redirect_uri_escape $scheme://$server_name:$server_port/login?request_uri=$request_uri_escape; # задаём и кодируем адрес возврата
    set_escape_uri $response_type_escape code; # задаём и кодируем тип ответа
    set_escape_uri $scope_escape $scope; # кодируем скоупы
    set_escape_uri $state_escape $state; # кодируем состояние
    set_escape_uri $timestamp_escape $timestamp; # кодируем дату-время
    return 303 https://esia.gosuslugi.ru/aas/oauth2/ac?access_type=$access_type_escape&client_id=$client_id_escape&client_secret=$client_secret_escape&redirect_uri=$redirect_uri_escape&response_type=$response_type_escape&scope=$scope_escape&state=$state_escape&timestamp=$timestamp_escape; # перенаправляем на ЕСИА

После успешной авторизации пользователя в ЕСИА, его перенаправляет на адрес возврата

location =/login {
    auth_request off; # не использовать авторизацию
    auth_jwt_key /data/nginx/esia.pub file; # задаём публичный ключ (который мы получили от ЕСИА) для расшифровки токена
    auth_jwt $arg_code; # задаём токен
    json_loads $jwt_grant_json $jwt_grant; # парсим тело токена в переменную
    json_dumps $oid $jwt_grant_json urn:esia:sbj urn:esia:sbj:oid; # извлекаем oid
    try_files /try?username=$oid; # перенаправляем на дальнейшую обработку
}
location =/try {
    internal;
    if ($arg_username = "") { return 401 UNAUTHORIZED; } # если oid не получен, то значит пользователь не авторизован
    encrypted_session_expires 43200; # задаём время жизни сессии 12 часов (12 * 60 * 60 = 43200)
    set_secure_random_alphanum $password 8; # задаём случайный пароль для basic авторизации
    set $username_password ESIA-$arg_username:$password; # задаём basic авторизацию
    set_encode_base64 $username_password_encode $username_password; # кодируем basic авторизацию
    set_encrypt_session $auth_encrypt $username_password_encode; # зашифровываем basic авторизацию
    set_encode_base64 $auth_encode $auth_encrypt; # кодируем зашифрованную basic авторизацию
    add_header Set-Cookie "Auth=$auth_encode; Max-Age=43200"; # помещаем зашифрованную basic авторизацию в авторизационную куку на 12 часов (12 * 60 * 60 = 43200)
    set $arg_request_uri_or_slash $arg_request_uri; # копируем запрос из аргумента
    set_if_empty $arg_request_uri_or_slash "/"; # если аргумент не задан, то начало
    set_unescape_uri $request_uri_unescape $arg_request_uri_or_slash; # раскодируем запрос
    return 303 $request_uri_unescape; # перенаправляем на сохранённый запрос
}
Похожее:  OAuth в SPA или неожиданные сложности интеграции логина через соцсети в React с Asp.Net Core — Пишем код

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *