Для приготовления авторизации через auth0 нам понадобится сам nginx и его плагины encrypted-session, headers-more, auth_request, set-misc, echo, json, evaluate и jwt. Можно также воспользоваться готовым образом.
Для начала, получим публичный ключ командой
curl https://our.application.domain.com/pem | openssl x509 -pubkey -noout > pub.key
Теперь, в конфиге зададим
encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";
Дальше отключаем авторизационный заголовок
more_clear_input_headers Authorization;
Теперь защищаем всё авторизацией
auth_request @auth; location @auth { # если нет авторизационной куки, то значит пользователь не авторизован if ($cookie_auth = "") { return 401 UNAUTHORIZED; } # раскодируем авторизационную куку set_decode_base64 $auth_decode $cookie_auth; # если не удалось раскодировать, то значит пользователь не авторизован if ($auth_decode = "") { return 401 UNAUTHORIZED; } # расшифровываем авторизационную куку set_decrypt_session $auth_decrypt $auth_decode; # если не удалось расшифровать, то значит пользователь не авторизован if ($auth_decrypt = "") { return 401 UNAUTHORIZED; } # подменяем авторизацию на basic (чтобы использовать переменную $remote_user) more_set_input_headers "Authorization: Basic $auth_decrypt"; echo -n OK; # пользователь авторизован }
Для авторизованных пользователей показываем контент из их папки
location / { alias html/$remote_user/; }
А при отсутствии авторизации перенаправляем на auth0
error_page 401 = @error; location @error { # задаём домен нашего приложения на auth0 set $domain our.application.domain.com; # задаём и кодируем идентификатор нашего приложения на auth0 set_escape_uri $client_id_escape YourApplicationClientID; # кодируем исходный запрос set_escape_uri $request_uri_escape $request_uri; # задаём и кодируем адрес возврата set_escape_uri $redirect_uri_escape https://$host/login?request_uri=$request_uri_escape; # задаём и кодируем тип ответа set_escape_uri $response_type_escape code; # задаём и кодируем скоупы set_escape_uri $scope_escape "openid profile"; # задаём и кодируем состояние set_escape_uri $state_escape 0; # перенаправляем клиента на auth0 return 303 https://$domain/authorize?client_id=$client_id_escape&redirect_uri=$redirect_uri_escape&response_type=$response_type_escape&scope=$scope_escape&state=$state_escape; }
После успешной авторизации пользователя в auth0, его перенаправляет на адрес возврата
location =/login { auth_request off; # не используем авторизацию evaluate $grant /grant; # получаем грант json_loads $grant_json $grant; # загружаем его json_dumps $aud $grant_json aud; # извлекаем идентификатор # если идентификатор не получен, то значит пользователь не авторизован if ($aud = "") { return 401 UNAUTHORIZED; } json_dumps $name $grant_json name; # извлекаем имя # задаём случайный пароль для basic авторизации set_secure_random_alphanum $password 8; # задаём и кодируем basic авторизацию set_encode_base64 $username_password_encode $name:$password; # зашифровываем basic авторизацию на 12 часов (12 * 60 * 60 = 43200) set_encrypt_session $auth_encrypt $username_password_encode 43200; # кодируем зашифрованную basic авторизацию set_encode_base64 $auth_encode $auth_encrypt; # помещаем зашифрованную basic авторизацию в авторизационную куку на 12 часов add_header Set-Cookie "Auth=$auth_encode; Max-Age=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; } location =/grant { internal; # запрос только для внутреннего использования # задаём и кодируем хост set_escape_uri $host_escape $host; # запрещаем сжимать ответ proxy_set_header Accept-Encoding deflate; # перенаправляем запрос на дополнительный локальный сервер proxy_pass http://localhost/grant?request_uri=$arg_request_uri&code=$arg_code&host=$host_escape; }
Для получения гранта используем дополнительный локальный сервер
server { listen localhost; # слушаем локально allow 127.0.0.1; # разрешаем только локальные подключения deny all; # и запрещаем все остальные location =/grant { evaluate $token @token; # получаем токен json_loads $token_json $token; # загружаем его json_dumps $id_token $token_json id_token; # извлекаем идентификационный токен auth_jwt $id_token; # задаём его в качестве jwt auth_jwt_alg RS256; # задаём тип токена auth_jwt_key /path/to/our/pub.key file; # задаём наш публичный ключ echo -n $jwt_grant; # отдаём тело токена } location @token { # задаём домен нашего приложения на auth0 set $domain our.application.domain.com; # задаём и кодируем идентификатор нашего приложения на auth0 set_escape_uri $client_id_escape YourApplicationClientID; # задаём и кодируем пароль нашего приложения на auth0 set_escape_uri $client_secret_escape YourApplicationClientSecret; # задаём и кодируем тип авторизации set_escape_uri $grant_type_escape authorization_code; # раскодируем хост set_unescape_uri $host_unescape $arg_host; # задаём и кодируем адрес возврата set_escape_uri $redirect_uri_escape https://$host_unescape/login?request_uri=$arg_request_uri; # задаём метод запроса proxy_method POST; # задаём тело запроса proxy_set_body client_id=$client_id_escape&code=$arg_code&redirect_uri=$redirect_uri_escape&client_secret=$client_secret_escape&grant_type=$grant_type_escape; # запрещаем сжимать ответ proxy_set_header Accept-Encoding deflate; # задаём тип тела запроса proxy_set_header Content-Type application/x-www-form-urlencoded; # разрешаем перелавать имя сервера proxy_ssl_server_name on; # перенаправляем запрос на auth0 proxy_pass https://$domain/oauth/token; } }
ссылка на оригинал статьи https://habr.com/ru/post/650911/
Добавить комментарий