Как стать автором
Обновить

Рецепты Nginx: авторизация через auth0

Время на прочтение3 мин
Количество просмотров8.1K

Для приготовления авторизации через 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

Далее, в конфиге

# отключаем авторизационный заголовок 
more_clear_input_headers Authorization;
# задаём домен нашего приложения на 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;

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

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; }
    # подменяем авторизацию на basic (чтобы использовать переменную $remote_user)
    more_set_input_headers "Authorization: Basic $auth_decrypt";
    echo -n OK; # пользователь авторизован
}

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

location / {
    alias html/$remote_user/; # показываем контент из их папки
}

А при отсутствии авторизации

error_page 401 = @auth;
location @auth {
    # задаём и кодируем скоупы
    set_escape_uri $scope_escape "openid profile";
    # перенаправляем клиента на auth0
    return 303 https://$domain/authorize?client_id=$client_id_escape&redirect_uri=$redirect_uri_escape&response_type=code&scope=$scope_escape&state=0;
}

После успешной авторизации пользователя в auth0, его перенаправляет на заданный адрес возврата

location =/login {
    auth_request off; # не используем авторизацию
    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; # задаём наш публичный ключ
    # и переходим к дальнейшей обработке
    redirect /continue?name=$jwt_grant_name&request_uri=$arg_request_uri;
}
location =/continue {
    auth_request off; # не используем авторизацию
    internal; # только для внутреннего использования
    # если имя не получено, то значит пользователь не авторизован
    if ($arg_name = "") { return 401 UNAUTHORIZED; }
    # задаём случайный пароль для basic авторизации
    set_secure_random_alphanum $password 8;
    # задаём и кодируем basic авторизацию
    set_encode_base64 $username_password_encode $arg_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 =/token {
    internal; # только для внутреннего использования
    # задаём и кодируем пароль нашего приложения на auth0
    set_escape_uri $client_secret_escape YourApplicationClientSecret;
    # задаём метод запроса
    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=authorization_code;
    # запрещаем сжимать ответ
    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;
}
Теги:
Хабы:
+5
Комментарии3

Публикации

Изменить настройки темы

Истории

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн