Для приготовления сервиса центральной авторизации нам понадобится сам nginx и его плагины encrypted-session, echo, headers-more, auth_request, eval, set-misc. (Я дал ссылки на свои форки, т.к. делал некоторые изменения, которые пока не удалось пропихнуть в оригинальные репозитории. Можно также воспользоваться готовым образом.)
Для серверной части нужно в конфигурацию сервера из авторизации ЕСИА, basic или LDAP добавить генерацию токена
А в конфигурации сервера клиента для начала зададим
Дальше, на всякий случай, отключаем авторизационный заголовок
Теперь защищаем всё авторизацией
Для авторизованных пользователей показываем контент из их папки
А при отсутствии авторизации перенаправляем на сервис центральной авторизации
После успешной авторизации, сервис центральной авторизации перенаправляет нас на указанный
Для серверной части нужно в конфигурацию сервера из авторизации ЕСИА, basic или LDAP добавить генерацию токена
location =/service {
set_decode_base64 $auth_decode $cookie_auth; # раскодируем авторизационную куку
set_decrypt_session $auth_decrypt $auth_decode; # расшифровываем авторизационную куку
if ($auth_decrypt) { # если удалось расшифровать, то значит пользователь авторизован
encrypted_session_expires 60; # задаём время жизни токена 1 минуту (1 * 60 = 60)
set_encrypt_session $token_encrypt $auth_decrypt; # зашифровываем токен
set_encode_base64 $token_encode $token_encrypt; # кодируем токен
set_escape_uri $token_escape $token_encode; # экранируем токен
set_unescape_uri $service_unescape $arg_service; # раскодируем переданный в аргументе сервис клиента
return 303 $service_unescape&token=$token_escape; # перенаправляем на сервис клиента с токеном
}
и проверку токена location =/serviceValidate {
set_unescape_uri $token_unescape $arg_token; # разэкранируем токен
set_decode_base64 $token_decode $token_unescape; # раскодируем токен
set_decrypt_session $token_decrypt $token_decode; # расшифровываем токен
return 200 $token_decrypt; # отдаём токен обратно на сервис клиента
}
А в конфигурации сервера клиента для начала зададим
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_escape_uri $request_uri_escape $request_uri; # кодируем запрос
set_escape_uri $service_escape $scheme://$server_name:$server_port/login?request_uri=$request_uri_escape; # составляем и кодируем адрес сервиса клиента
return 303 https://$cas/service?service=$service_escape; # перенаправляем на сервис центральной авторизации, где $cas - это его адрес
}
После успешной авторизации, сервис центральной авторизации перенаправляет нас на указанный
location =/login {
eval $auth { # создаём запрос на проверку токена (полученного от сервиса центральной авторизации)
proxy_set_header X-Real-IP $remote_addr; # пробрасываем реальный адрес
proxy_pass $scheme://$cas:$server_port/serviceValidate?token=$arg_token; # проверяем токен
}
if ($auth = "") { return 401 UNAUTHORIZED; } # если токен не получен, то значит пользователь не авторизован
encrypted_session_expires 43200; # задаём время жизни сессии 12 часов (12 * 60 * 60 = 43200)
set_encrypt_session $auth_encrypt $auth; # зашифровываем токен-авторизацию
set_encode_base64 $auth_encode $auth_encrypt; # кодируем авторизацию
add_header Set-Cookie "Auth=$auth_encode; Max-Age=43200"; # помещаем авторизацию в куку на 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; # перенаправляем на сохранённый запрос
}