OIDC: Difference between revisions

From Svacer Wiki
(Created page with "== Основные концепции == Аутентификация с помощью протокола OpenID Connect (далее OIDC) реализована с помощью утилиты [https://oauth2-proxy.github.io/oauth2-proxy/ oauth2-proxy]. Общая схема аутентификации представлена на рисунке ниже: thumb Пояснения к картинке указаны в табл...")
 
(minor fixes)
 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
== Основные концепции ==
== Основные концепции ==


Аутентификация с помощью протокола OpenID Connect (далее OIDC) реализована с помощью утилиты [https://oauth2-proxy.github.io/oauth2-proxy/ oauth2-proxy]. Общая схема аутентификации представлена на рисунке ниже:
Аутентификация с помощью протокола ''OpenID Connect'' (далее ''OIDC'') реализована с помощью утилиты [https://oauth2-proxy.github.io/oauth2-proxy/ oauth2-proxy]. Общая схема аутентификации представлена на рисунке ниже:


[[File:Image-20240531112418954.png|thumb]]
[[File:Image-20240531112418954.png|thumb|none]]


Пояснения к картинке указаны в таблице.  
Пояснения к картинке указаны в таблице.  


{|
{| class="wikitable"
! шаг
! Шаг
! Описание
! Описание
|-
|-
| 1. Запрос ресурса
| 1. Запрос ресурса
| Если запрос включен в список запросов без аутентификации (см skip_auth_routes), то он перенаправляется к серверу Svacer (Входа на сервер Svacer при этом не происходит. Будут доступны только те ресурсы, которые не требуют аутентификации). Если запроса нет в списке, то переходим к шагу 2
| Если запрос включен в список запросов без аутентификации (см. skip_auth_routes), то он перенаправляется к серверу Svacer (Входа на сервер Svacer при этом не происходит. Будут доступны только те ресурсы, которые не требуют аутентификации). Если запроса нет в списке, то переходим к шагу 2
|-
|-
| 2. Проверка необходимости аутентификации OAuth2
| 2. Проверка необходимости аутентификации OAuth2
| Утилита oAuth2-proxy, на основе имеющихся в куках данных, определяет необходимость перенаправления пользователя на сервер OAuth2. Если аутентификация необходима, то по по URL, который был указан в параметре oidc_issuer_url, прокси запросит точки входа в соответствии с протоколом OIDC. После получения нужной точки входа, пользователь будет перенеаправлен на нее (шаг 3), при этом в параметре redirect этого запроса будет указано значение параметра конфигурации прокси redirect_url. Если аутентификация не нужна (уже есть действительный токен от OIDC сервера), то запрос перенаправляется на сервер Svacer (с токеном доступа (Access Token) от сервера OAuth2 в заголовке X-Forwarded-Access-Token) - шаг 1* на рисунке
| Утилита oAuth2-proxy, на основе имеющихся в куках данных, определяет необходимость перенаправления пользователя на сервер OAuth2. Если аутентификация необходима, то по URL, который был указан в параметре oidc_issuer_url, прокси запросит точки входа в соответствии с протоколом OIDC. После получения нужной точки входа, пользователь будет перенаправлен на нее (шаг 3), при этом в параметре redirect этого запроса будет указано значение параметра конфигурации прокси redirect_url. Если аутентификация не нужна (уже есть действительный токен от OIDC сервера), то запрос перенаправляется на сервер Svacer с токеном доступа (Access Token) от сервера OAuth2 в заголовке X-Forwarded-Access-Token шаг 1* на рисунке
|-
|-
| 3. Аутентификация пользователя на OAuth2 сервере
| 3. Аутентификация пользователя на OAuth2 сервере
| Если в куках сервера OAuth2 есть данные об активной сессии аутентификации, то пользователь будет перенаправлен обратно на прокси сервер (по указанному в параметре запроса URL). При этом, в параметрах URL будет передан Authorization Code для дальнейшего использования клиентом OAuth2 (в терминологии OAuth2 клиентом является oauth2-proxy). Если активной сессии нет, то будет отображена форма для логина и пароля пользователя. После успешного входа, OAuth2 сервер запомнит сессию пользователя, сформирует Authorization Code и перенаправит пользователя обратно на прокси, передав в URL значение Authorization Code
| Если в куках сервера OAuth2 есть данные об активной сессии аутентификации, то пользователь будет перенаправлен обратно на прокси сервер по указанному в параметре запроса URL. При этом, в параметрах URL будет передан Authorization Code для дальнейшего использования клиентом OAuth2 (в терминологии OAuth2 клиентом является oauth2-proxy). Если активной сессии нет, то будет отображена форма для логина и пароля пользователя. После успешного входа, OAuth2 сервер запомнит сессию пользователя, сформирует Authorization Code и перенаправит пользователя обратно на прокси, передав в URL значение Authorization Code
|-
|-
| 4. Получение AccessToken
| 4. Получение AccessToken
| Прокси осуществляет получение Access Token от сервера OAuth2, используя полученный Authorization Code и точку входа сервера OAuth2 для получения токенов, которую он получил ранее на шаге 2.
| Прокси осуществляет получение Access Token от сервера OAuth2, используя полученный Authorization Code и точку входа сервера OAuth2 для получения токенов, которую он получил ранее на шаге 2
|-
|-
| 5. Отправка запроса к Svacer
| 5. Отправка запроса к Svacer
Line 32: Line 32:
== Конфигурация Svacer для поддержки протокола OIDC ==
== Конфигурация Svacer для поддержки протокола OIDC ==


Для конфигурации svacer необходимо использовать секцию '''''auth''''' стандартного конфигурационного файла svacer, указываемого через опцию --config при запуске svacer.  
Для конфигурации Svacer необходимо использовать секцию ''auth'' стандартного конфигурационного файла Svacer, указываемого через опцию ''--config'' при его запуске.  


<pre class="">svacer-server run --config config.yaml</pre>
svacer-server run --config config.yaml
Пример секции auth конфигурационного файла представлен ниже


<source lang="yaml">auth:
Пример секции ''auth'' конфигурационного файла представлен ниже
  oidc:
  oidc:
   enabled: true
   enabled: true
Line 44: Line 43:
   enabled: true
   enabled: true
   clock: 1
   clock: 1
   sign_in: "http://zeus.intra.ispras.ru:12800/realms/svacer/protocol/openid-connect/token"
   sign_in: "<nowiki>http://keycloak:12800/realms/svacer/protocol/openid-connect/token</nowiki>"
   sign_out: "http://hadokku.intra.ispras.ru:4180/oauth2/sign_out?rd=/oauth2/sign_in"
   sign_out: "<nowiki>http://oauth_proxy:4180/oauth2/sign_out?rd=/oauth2/sign_in</nowiki>"
   tokens:
   tokens:
     - claims:
     - claims:
Line 57: Line 56:
       - key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvR/zIW/acyWFVSuSD/8iDM3epguHljKZkaB4ITojRwisXNcn6S0ArlI8v69qV1tBFi+RH3Ys4L5Pj+xDFlemlml6wPp5X0tcD2Gax51KHqQcFjViBGVSqJUdts/bkvfiIfZLkurybkhR0ALToWvbNyD7>
       - key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvR/zIW/acyWFVSuSD/8iDM3epguHljKZkaB4ITojRwisXNcn6S0ArlI8v69qV1tBFi+RH3Ys4L5Pj+xDFlemlml6wPp5X0tcD2Gax51KHqQcFjViBGVSqJUdts/bkvfiIfZLkurybkhR0ALToWvbNyD7>
         name: rsa
         name: rsa
</source>
В секции используются следующие поля:
В секции используются следующие поля:


{|
{| class="wikitable"
! Название
! Название
! Описание
! Описание
|-
|-
| '''''enabled'''''
| '''''enabled'''''
| Использовать OIDC провайдер. Значение '''false''' отключает данный функционал
| Использовать ''OIDC'' провайдер. Значение ''false'' отключает данный функционал
|-
|-
| '''''debug'''''
| '''''debug'''''
| Выводить в логи сервера дополнительные отладочные сообщения. Полезно при первичной настройке, в дальнейшем желательно установить в значение '''false'''
| Выводить в логи сервера дополнительные отладочные сообщения. Полезно при первичной настройке, в дальнейшем желательно установить в значение ''false''
|-
|-
| '''''oauth_proxy.enabled'''''
| '''''oauth_proxy.enabled'''''
| Использовать утилиту '''oauth2-proxy''' в качестве механизма поддержки протокола OIDC. На текущий момент это единственная реализация поддержки OIDC протокола
| Использовать утилиту ''oauth2-proxy'' в качестве механизма поддержки протокола OIDC. На текущий момент это единственная реализация поддержки ''OIDC'' протокола
|-
|-
| '''''oauth_proxy.clock'''''
| '''''oauth_proxy.clock'''''
Line 77: Line 75:
|-
|-
| '''''oauth_proxy.sign_in'''''
| '''''oauth_proxy.sign_in'''''
| Точка входа сервера OAuth2 для получения токена. Используется в Svacer только для работы cli команд и сервисной учетной записи. При некорректном значении работа Svacer клиента с сервером Svacer через OIDC будет невозможна. В случае правильной настройки других параметров, в GUI пользователи работать смогут.
| Точка входа сервера OAuth2 для получения токена. Используется в Svacer только для работы CLI команд и сервисной учетной записи. При некорректном значении работа клиента Svacer с сервером Svacer через ''OIDC'' будет невозможна, но при правильной настройке других параметров, в GUI пользователи работать смогут
|-
|-
| '''''oauth_proxy.sign_out'''''
| '''''oauth_proxy.sign_out'''''
| Ссылка, которая будет использована при выходе пользователя из системы (logout в GUI). Более подробно см. Выход пользователя из системы
| Ссылка, которая будет использована при выходе пользователя из системы (logout в GUI). Более подробно см. [[OIDC#Выход_пользователя_из_системы|Выход пользователя из системы]]
|-
|-
| '''''oauth_proxy.tokens'''''
| '''''oauth_proxy.tokens'''''
| Массив объектов (''token''), описывающих структуру JWT токена OIDC сервера и данные, необходимые для проверки выпускаемого им токена
| Массив объектов (''token''), описывающих структуру ''JWT'' токена ''OIDC'' сервера и данные, необходимые для проверки выпускаемого им токена
|-
|-
| '''''token.claims'''''
| '''''token.claims'''''
Line 104: Line 102:
|-
|-
| '''''token.claims.role'''''
| '''''token.claims.role'''''
| Название поля из Claims токена, значение которого будет использовано для добавления роли пользователю Svacer. Значение должно быть именем уже существующей роли или значением &quot;admin&quot; для добавления роли администратора. Автоматическое назначение роли происходит только при первом создании пользователя
| Название поля из Claims токена, значение которого будет использовано для добавления роли пользователю Svacer. Значение должно быть именем уже существующей роли или значением "admin" для добавления роли администратора. Автоматическое назначение роли происходит только при первом создании пользователя
|-
|-
| '''''token.sign'''''
| '''''token.sign'''''
| Содержит данные, необходимые для проверки подписи JWT токена
| Содержит данные, необходимые для проверки подписи ''JWT'' токена
|-
|-
| '''''token.sign.key'''''
| '''''token.sign.key'''''
Line 121: Line 119:
== Конфигурация OAuth2-proxy  ==
== Конфигурация OAuth2-proxy  ==


Конфигурация oauth2-proxy может выполнятся через параметры cli, через указание параметров в конфигурационном файле, а также через переменные окружения. Названия параметров, передаваемых в cli, в конфигурационном файле и через cli находятся в следующем соответствии друг с другом (на примере параметра client_secret):
Конфигурация OAauth2-proxy может выполнятся через параметры CLI, через указание параметров в конфигурационном файле, а также через переменные окружения. Названия параметров, передаваемых в CLI, в конфигурационном файле и через переменные окружения находятся в следующем соответствии друг с другом (на примере параметра ''client_secret''):


{|
{| class="wikitable"
! КОнфигурационный файл
! Конфигурационный файл
! CLI
! CLI
! Переменная окружения
! Переменная окружения
Line 133: Line 131:
|}
|}


'''Для нормальной работы желательно наличие DNS имен для хостов (OAuth2-proxy использует Cookies для хранения там информации о сессии аутентификации пользователя а также для хранения csrf токена)''' . Ниже приводится пример конфигурации oauth2-proxy для подключения svacer сервера к OAuth2 серверу KeyCloak
'''Для нормальной работы желательно наличие DNS имен для хостов (OAuth2-proxy использует Cookies для хранения там информации о сессии аутентификации пользователя а также для хранения csrf токена).'''


Ниже приводится пример конфигурации oauth2-proxy для подключения Svacer сервера к OAuth2 серверу Keycloak
<pre class="">standard_logging = true
<pre class="">standard_logging = true
standard_logging_format = &quot;[{{.Timestamp}}] [{{.File}}] {{.Message}}&quot;
standard_logging_format = "[{{.Timestamp}}] [{{.File}}] {{.Message}}"
auth_logging = true
auth_logging = true
auth_logging_format = &quot;{{.Client}} - {{.Username}} [{{.Timestamp}}] [{{.Status}}] {{.Message}}&quot;
auth_logging_format = "{{.Client}} - {{.Username}} [{{.Timestamp}}] [{{.Status}}] {{.Message}}"
pass_user_headers = true
pass_user_headers = true
pass_host_header = true
pass_host_header = true
email_domains = [
email_domains = [
  &quot;*&quot;
  "*"
]
]
client_id = &quot;svacer-auth-proxy&quot;
client_id = "svacer-auth-proxy"
client_secret = &quot;q2rNKGofxpw7FzmZDstSIyNNyzkW1BsW&quot;
client_secret = "q2rNKGofxpw7FzmZDstSIyNNyzkW1BsW"
pass_access_token = true
pass_access_token = true
cookie_name = &quot;_oauth2_proxy2&quot;
cookie_name = "_oauth2_proxy2"
cookie_secret = &quot;2-W9DDrnlfBEK75F3zGpszuwTSqwBcUFQm6OQa3dHgU=&quot;
cookie_secret = "2-W9DDrnlfBEK75F3zGpszuwTSqwBcUFQm6OQa3dHgU="
cookie_expire = &quot;11m&quot;
cookie_expire = "11m"
cookie_refresh = &quot;10m&quot;
cookie_refresh = "10m"
cookie_secure = false
cookie_secure = false
provider = &quot;keycloak-oidc&quot;
provider = "keycloak-oidc"
show_debug_on_error = true
show_debug_on_error = true
cookie_csrf_per_request = true
cookie_csrf_per_request = true
cookie_csrf_expire = &quot;36h&quot;
cookie_csrf_expire = "36h"
skip_auth_routes = [&quot;GET=/static/.*&quot;,&quot;/api/public/*&quot;,&quot;GET=/api/auth_settings&quot;]
skip_auth_routes = ["GET=/static/.*","/api/public/*","GET=/api/auth_settings"]
</pre>
</pre>
В файле выше указаны не все требуемые параметры для нормальной работы oauth2-proxy. Ниже приведены наиболее важные параметры конфигурационного файла oauth2-proxy с пояснениями
В файле выше указаны не все требуемые параметры для нормальной работы OAuth2-proxy. Ниже приведены наиболее важные параметры конфигурационного файла OAuth2-proxy с пояснениями


{|
{| class="wikitable"
! Название
! Название
! Описание
! Описание
Line 183: Line 182:
|-
|-
| http_address
| http_address
| Имя хоста, на котором будет работать oauth2-proxy. (см. пример в секцию &quot;Конфигурация в Docker&quot;)
| Имя хоста, на котором будет работать OAuth2-proxy, см. пример в разделе [[OIDC#Конфигурация_в_Docker|Конфигурация в Docker]]
|-
|-
| upstreams
| upstreams
| Хост, на котором работает Svacer (см. пример в секцию &quot;Конфигурация в Docker&quot;)
| Хост, на котором работает Svacer, см. пример в разделе [[OIDC#Конфигурация_в_Docker|Конфигурация в Docker]]
|-
|-
| redirect_url
| redirect_url
| URL на который будет осуществлено перенаправление после успешной аутентификации на OAuth2 сервере (см. пример в секцию &quot;Конфигурация в Docker&quot;)
| URL на который будет осуществлено перенаправление после успешной аутентификации на OAuth2 сервере, см. пример в разделе [[OIDC#Конфигурация_в_Docker|Конфигурация в Docker]]
|-
|-
| oidc_issuer_url
| oidc_issuer_url
| URL сервера OAuth2 для начала аутентификации (см. пример в секцию &quot;Конфигурация в Docker&quot;). С помощью данного URL будет получен список точек входа для поддержки разных потоков аутентификации (в терминах OAuth2)
| URL сервера OAuth2 для начала аутентификации, см. пример в разделе [[OIDC#Конфигурация_в_Docker|Конфигурация в Docker]]. С помощью данного URL будет получен список точек входа для поддержки разных потоков аутентификации (в терминах OAuth2)
|}
|}


=== Детали работы oauth2-proxy с куками и токенами ===
=== Детали работы OAuth2-proxy с куками и токенами ===


Для корректной настройки oauth2-proxy полезно понимать детали работы ouath2-proxy. На шаге 2 прокси определяет необходимость выполнения аутентификации пользователя. Прокси проверяет наличие куки _oauth2_proxy и его срок действия. Срок действия создаваемых кук указывается в поле cookie_expire. Если срок действия куки закончен, то пользователь будут перенаправлен на точку входа прокси: /oauth2/sign_in.
Для корректной настройки OAuth2-proxy полезно понимать детали работы OAath2-proxy. На шаге 2 прокси определяет необходимость выполнения аутентификации пользователя. Прокси проверяет наличие куки ''_oauth2_proxy'' и его срок действия. Срок действия создаваемых кук указывается в поле ''cookie_expire''. Если срок действия куки закончен, то пользователь будут перенаправлен на точку входа прокси: ''/oauth2/sign_in''.


Важным полем конфигурации является поле cookie_refresh. При каждом запросе, прокси обновляет свои куки с периодичностью, указанной в cookie_refresh. Вместе с обновлением своих куки прокси проверяет состояние сессии на OAuth2 сервере и получает новый токен доступа. То есть, если в поле cookie_refresh стоит значение 1 минута, 1 раз в минуту (если пользователь отправляет запросы 1 раз в 10 секунд, то каждый 6 запрос будет обновлять куки прокси) oauth2-proxy будет обновлять свои куки _oauth2_proxy и обновлять состоянии сессии аутентификации на сервере OAuth2 с получением токена доступа. Если сессия OAuth2 завершена, пользователь будет перенаправлен на точку входа аутентификации сервера OAuth2.  
Важным полем конфигурации является поле ''cookie_refresh''. При каждом запросе прокси обновляет свои куки с периодичностью, указанной в ''cookie_refresh''. Вместе с обновлением своих куки прокси проверяет состояние сессии на OAuth2 сервере и получает новый токен доступа. То есть, если в поле ''cookie_refresh'' стоит значение 1 минута, 1 раз в минуту (если пользователь отправляет запросы 1 раз в 10 секунд, то каждый 6 запрос будет обновлять куки прокси) OAuth2-proxy будет обновлять свои куки ''_oauth2_proxy'' и обновлять состоянии сессии аутентификации на сервере OAuth2 с получением токена доступа. Если сессия OAuth2 завершена, пользователь будет перенаправлен на точку входа аутентификации сервера OAuth2.  


== Выход пользователя из системы ==
== Выход пользователя из системы ==


Процедура выхода пользователя из Svacer состоит из двух этапов. На первом этапе производится инвалидация токена Svacer, далее осуществляется переход по ссылке указанной в параметре '''''oauth_proxy.sign_out''''' с тем, чтобы прокси сервер или/и OAuth сервер смогли выполнить инвалидацию сущностей аутентификации, выданных пользователю. Явным признаком корректной работы выхода пользователя из системы является отсутствие данных аутентификации в куках сервера OAuth (и/или прокси) после выхода пользователя из системы.
Процедура выхода пользователя из Svacer состоит из двух этапов. На первом этапе производится инвалидация токена Svacer, далее осуществляется переход по ссылке указанной в параметре ''oauth_proxy.sign_out'' с тем, чтобы прокси сервер или/и OAuth2 сервер смогли выполнить инвалидацию сущностей аутентификации, выданных пользователю. Явным признаком корректной работы выхода пользователя из системы является отсутствие данных аутентификации в куках сервера OAuth2 (и/или прокси) после выхода пользователя из системы.


== Работа со Svacer через cli ==
== Работа со Svacer через CLI ==


Работа в CLI происходит через специальную учетную запись в OAuth сервере, которая не требует аутентификации пользователя через web форму. Для этой цели используется [https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow Client Credentials Flow] из спецификации OAuth2. На OAuth2 сервере требуется создание пары client@secret и настройки правил формирования JWT токена, соответствующего настройкам OIDC Svacer. Наиболее важным моментом является наличие такого поля в Claims токена, которое было указано в конфигурации Svacer, в поле token.claims.subject. После успешного входа на сервер Svacer, будет создан локальный пользователь Svacer, соответствующий субъекту токена OAuth2. Пользователю также будет назначена роль, указанная в token.claims.role, если она будет найдена. По этой причине рекомендуется перед первым использованием Svacer совместно с сервером OIDC настроить роли в Svacer.  
Работа в CLI происходит через специальную учетную запись в OAuth2 сервере, которая не требует аутентификации пользователя через web форму. Для этой цели используется [https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow Client Credentials Flow] из спецификации OAuth2''. На OAuth2 сервере требуется создание пары ''client@secret'' и настройки правил формирования ''JWT'' токена, соответствующего настройкам ''OIDC'' в Svacer. Наиболее важным моментом является наличие такого поля в Claims токена, которое было указано в конфигурации Svacer, в поле ''token.claims.subject''. После успешного входа на сервер Svacer, будет создан локальный пользователь Svacer, соответствующий субъекту токена OAuth2. Пользователю также будет назначена роль, указанная в token.claims.role, если она будет найдена. По этой причине рекомендуется перед первым использованием Svacer совместно с сервером ''OIDC'' настроить роли в Svacer.  


Процесс аутентификации пользователя cli в Svacer с использованием OIDC сервера происходит следующим образом:
Процесс аутентификации пользователя CLI в Svacer с использованием OIDC сервера происходит следующим образом:


# Клиент запрашивает настройки сервера Svacer (по этой причине /api/settings должен проходить через прокси без аутентификации)
# Клиент запрашивает настройки сервера Svacer (по этой причине ''/api/settings'' должен проходить через прокси без аутентификации)
# В полученных настройках считывается значение, соответствующее полю oauth_proxy.sign_in
# В полученных настройках считывается значение, соответствующее полю ''oauth_proxy.sign_in''
# Полученная на втором этапе ссылка, используется для получения токена доступа от сервера OAuth2
# Полученная на втором этапе ссылка, используется для получения токена доступа от сервера OAuth2
# Полученный на 3 шаге токен, обменивается на токен Svacer, с помощью запроса: POST; /api/public/oidc/login. Данный запрос должен быть включен в список запросов, не требующих аутентификации (см. пример конфигурации oauth2-proxy)  
# Полученный на 3 шаге токен, обменивается на токен Svacer, с помощью запроса: POST ''/api/public/oidc/login''. Данный запрос должен быть включен в список запросов, не требующих аутентификации (см. пример [[OIDC#Конфигурация_OAuth2-proxy|конфигурации OAuth2-proxy]])  


В виду всего вышесказанного, в конфигурационном файле oauth2-proxy надо делать исключения на  
В виду всего вышесказанного, в конфигурационном файле OAuth2-proxy надо делать исключения на  


* запрос /api/public/oidc/login (иначе прокси будет пытаться аутентифицировать их, выдавая веб форму для аутентификации пользователя)
* запрос ''/api/public/oidc/login'' (иначе прокси будет пытаться аутентифицировать их, выдавая веб форму для аутентификации пользователя)
* запрос /api/settings
* запрос ''/api/settings''


== Возможные проблемы при настройке ==
== Возможные проблемы при настройке ==


=== Keycloak; Cookies not found ===
=== Сообщение 'Cookies not found' ===


Проблема в DNS имена хоста Keycloak. Проблема встречается когда хост Keycloak имеет разные имена.
Проблема в DNS имена хоста Keycloak. Проблема встречается когда хост Keycloak имеет разные имена или в некоторых случаях обращение к нему происходит по IP адресу.


=== Keycloak; Invalid parametr: redirect_url ===
=== Сообщение 'Invalid parameter: redirect_url' ===


[[File:Image-20240529151256529.png|thumb]]
[[File:Image-20240529151256529.png|thumb|none]]


При перенаправлении пользователя на Keycloak сервер, OAuth2-proxy передал неверное значение в параметре redirect_uri. Необходимо проверить, что в настройках Keycloak и в параметре redirect_uri oauth2-proxy находятся одинаковые значения
При перенаправлении пользователя на Keycloak сервер, OAuth2-proxy передал неверное значение в параметре ''redirect_uri''. Необходимо проверить, что в настройках Keycloak и в параметре ''redirect_uri'' OAauth2-proxy находятся одинаковые значения
 
[[File:Image-20240529152158450.png|thumb]]
 
=== OAuth2-proxy; CSRF cookie failed validation ===
<ref>
[[File:Image-20240529154038778.png|thumb]]
</ref>


[[File:Image-20240529152158450.png|thumb|none]]


=== Сообщение 'CSRF cookie failed validation' ===
Данная ошибка появляется по следующим причинам:
Данная ошибка появляется по следующим причинам:
* ''csrf'' токен не найден в куках; Можно открыть консоль разработчика и убедится, что в куках для хоста oauth2-proxy есть кука: ''_oauth2_proxy_csrf_XXXXX''
* ''csrf'' токен истек; Для решения проблемы можно увеличить время действия ''csrf'' токена (см. [[OIDC#Конфигурация_OAuth2-proxy|Конфигурация OAuth2-proxy]])
* был произведен перезапуск oauth2-proxy, а строка адреса в URL осталась от предыдущего запуска; Попробовать начать процедуру входа снова, перейдя на главную страницу OAuth2-proxy


* csrf токен не найден в куках; Можно открыть консоль разработчика и убедится, что в куках для хоста oauth2-proxy есть кука: _oauth2_proxy_csrf_XXXXX
=== Строка переключения языка GUI Svacer и белый экран. ===
* csrf токен истек; Для решения проблемы, можно увеличить время действия csrf токена (см конфигурация OAuth2-proxy)
* был произведен перезапуск oauth2-proxy, а строка адреса в URL осталась от предыдущего запуска; Попробовать начать процедуру входа снова, перейдя на главную страницу oauth2-proxy
 
=== OAuth2-proxy; Строка переключения языка GUI Svacer и белый экран. ===
 
[[File:Image-20240529172343611.png|thumb]]


Сервер Svacer недоступен.
Сервер Svacer недоступен.


=== При работе с CLI возникает ошибка: ''Failed to query server. Details: server response error: 403'' ===
=== При работе с CLI возникает ошибка: 'Failed to query server. Details: server response error: 403' ===


Не прописано исключение для запроса: /''api/public/server/info''
Не прописано исключение для запроса: /''api/public/server/info''


=== При работе с CLI возникает ошибка: ''cannot get authentication settings from server StatusCode:403'' ===
=== При работе с CLI возникает ошибка: 'Cannot get authentication settings from server StatusCode: 403' ===


Не прописано исключение для запроса: ''/api/auth_settings''
Не прописано исключение для запроса: ''/api/auth_settings''


=== При работе с CLI возникает ошибка: ''ERROR: invalid character '&lt;' looking for beginning of value'' ===
=== При работе с CLI возникает ошибка: 'ERROR: invalid character '<' looking for beginning of value' ===


Не прописано исключение для запроса: ''/api/public/oidc/login''
Не прописано исключение для запроса: ''/api/public/oidc/login''


== Дополнение ==
== Конфигурация в Docker ==


Ниже приводятся примеры конфигурации контейнеров для запуска Svacer в тестовом режиме с целью понимая логики работы oauth2-proxy совместно со Svacer и сервером Keycloak.
Ниже приводятся примеры конфигурации контейнеров для запуска Svacer в тестовом режиме с целью понимания логики работы oauth2-proxy совместно со Svacer и сервером Keycloak.


== Образы ==
=== Образы Docker ===


=== Svacer ===
==== Svacer ====


Dockerfile:
Файл Dockerfile:


<pre class="">FROM ubuntu:22.04
<pre class="">FROM ubuntu:22.04


LABEL maintainer=&quot;akuzmin@ispras.ru&quot;
LABEL maintainer="akuzmin@ispras.ru"


ARG DEBIAN_FRONTEND=noninteractive
ARG DEBIAN_FRONTEND=noninteractive
Line 299: Line 290:
CMD /svacer/bin/svacer-server --memsettings=${MEMSETTINGS} run --store $STORE --pg $SVACER_PG_URL --config /config/config.yaml
CMD /svacer/bin/svacer-server --memsettings=${MEMSETTINGS} run --store $STORE --pg $SVACER_PG_URL --config /config/config.yaml
</pre>
</pre>
=== Oauth2-proxy ===


Dockerfile:
==== OAuth2-proxy ====
 
Файл Dockerfile:


<pre class="">FROM ubuntu:22.04
<pre class="">FROM ubuntu:22.04
LABEL maintainer=&quot;chernykov_sv@ispras.ru&quot;
LABEL maintainer="chernykov_sv@ispras.ru"
RUN mkdir /config
RUN mkdir /config
RUN mkdir /logs
RUN mkdir /logs
Line 312: Line 304:
COPY start.sh start.sh
COPY start.sh start.sh
RUN apt update &amp;&amp; apt install curl -y
RUN apt update &amp;&amp; apt install curl -y
ENTRYPOINT [&quot;/bin/bash&quot;, &quot;-c&quot;, &quot;/oauth/start.sh&quot;]
ENTRYPOINT ["/bin/bash", "-c", "/oauth/start.sh"]
</pre>
</pre>
Скрипт start.sh (полезен для определения факта запуска Keycloak контейнера):
Скрипт start.sh (полезен для определения факта запуска Keycloak контейнера):
Line 320: Line 312:
start='no'
start='no'
tmt=60
tmt=60
echo &quot;Using $KEYCLOAK_HOST&quot;
echo "Using $KEYCLOAK_HOST"
until [[ $exit == 'yes' ]]; do
until [[ $exit == 'yes' ]]; do
   sleep 5
   sleep 5
Line 339: Line 331:
./oauth2-proxy --config /config/oauth.cfg --logging-filename /logs/oauth.log
./oauth2-proxy --config /config/oauth.cfg --logging-filename /logs/oauth.log
else
else
  echo &quot;Keycloak is not ready ...Can not start oauth2_proxy&quot;
  echo "Keycloak is not ready ...Can not start oauth2_proxy"
fi
fi
</pre>
</pre>
Docker-compose


<pre class="">version: &quot;3.6&quot;
=== Docker-compose ===
Файл docker-compose.yml


<pre class="">version: "3.6"
services:
services:
   oauth_proxy:
   oauth_proxy:
Line 364: Line 357:
           condition: service_healthy
           condition: service_healthy
     ports:
     ports:
       - &quot;4180:8080&quot;
       - "4180:8080"
     networks:
     networks:
       svacer_oauth:
       svacer_oauth:
Line 380: Line 373:
       - POSTGRES_ROOT_PASSWORD=svace
       - POSTGRES_ROOT_PASSWORD=svace
     expose:
     expose:
       - &quot;5432&quot;
       - "5432"
     volumes:
     volumes:
       - ./postgres_data:/var/lib/postgresql/data
       - ./postgres_data:/var/lib/postgresql/data
Line 408: Line 401:
       - ./keycloak_realm:/opt/keycloak/data/import
       - ./keycloak_realm:/opt/keycloak/data/import
     ports:
     ports:
       - &quot;8888:8888&quot;
       - "8888:8888"
     expose:
     expose:
       - &quot;8888&quot;
       - "8888"
     networks:
     networks:
       svacer_oauth:
       svacer_oauth:
Line 430: Line 423:
         condition: service_healthy
         condition: service_healthy
     ports:
     ports:
       - &quot;3002:3002&quot;
       - "3002:3002"
       - &quot;18080:8080&quot;
       - "18080:8080"
     volumes:
     volumes:
       - ./svacer_data:/data
       - ./svacer_data:/data

Latest revision as of 18:12, 3 June 2024

Основные концепции

Аутентификация с помощью протокола OpenID Connect (далее OIDC) реализована с помощью утилиты oauth2-proxy. Общая схема аутентификации представлена на рисунке ниже:

Пояснения к картинке указаны в таблице.

Шаг Описание
1. Запрос ресурса Если запрос включен в список запросов без аутентификации (см. skip_auth_routes), то он перенаправляется к серверу Svacer (Входа на сервер Svacer при этом не происходит. Будут доступны только те ресурсы, которые не требуют аутентификации). Если запроса нет в списке, то переходим к шагу 2
2. Проверка необходимости аутентификации OAuth2 Утилита oAuth2-proxy, на основе имеющихся в куках данных, определяет необходимость перенаправления пользователя на сервер OAuth2. Если аутентификация необходима, то по URL, который был указан в параметре oidc_issuer_url, прокси запросит точки входа в соответствии с протоколом OIDC. После получения нужной точки входа, пользователь будет перенаправлен на нее (шаг 3), при этом в параметре redirect этого запроса будет указано значение параметра конфигурации прокси redirect_url. Если аутентификация не нужна (уже есть действительный токен от OIDC сервера), то запрос перенаправляется на сервер Svacer с токеном доступа (Access Token) от сервера OAuth2 в заголовке X-Forwarded-Access-Token — шаг 1* на рисунке
3. Аутентификация пользователя на OAuth2 сервере Если в куках сервера OAuth2 есть данные об активной сессии аутентификации, то пользователь будет перенаправлен обратно на прокси сервер по указанному в параметре запроса URL. При этом, в параметрах URL будет передан Authorization Code для дальнейшего использования клиентом OAuth2 (в терминологии OAuth2 клиентом является oauth2-proxy). Если активной сессии нет, то будет отображена форма для логина и пароля пользователя. После успешного входа, OAuth2 сервер запомнит сессию пользователя, сформирует Authorization Code и перенаправит пользователя обратно на прокси, передав в URL значение Authorization Code
4. Получение AccessToken Прокси осуществляет получение Access Token от сервера OAuth2, используя полученный Authorization Code и точку входа сервера OAuth2 для получения токенов, которую он получил ранее на шаге 2
5. Отправка запроса к Svacer Первоначальный запрос (из шага 1), отправляется серверу Svacer. При этом в заголовки этого запроса добавляется Access Token от OAuth сервера, а также другие специфичные для oauth2-proxy заголовки. Состав дополнительной информации, передаваемой в заголовках, определяется конфигурацией oauth2-proxy
6. Выпуск токена Svacer Svacer определяет наличие заголовка X-Forwarded-Access-Token в запросе. Если конфигурация сервера подразумевает использование OIDC протокола, то полученный токен проверяется и на его основе создается токен Svacer, после чего выполняется вход в систему и создается пользователь Svacer (если еще не создан), соответствующий пользователю, указанному в токене доступа от OAuth2 сервера

Конфигурация Svacer для поддержки протокола OIDC

Для конфигурации Svacer необходимо использовать секцию auth стандартного конфигурационного файла Svacer, указываемого через опцию --config при его запуске.

svacer-server run --config config.yaml

Пример секции auth конфигурационного файла представлен ниже

oidc:
 enabled: true
 debug: true
 oauth_proxy:
  enabled: true
  clock: 1
  sign_in: "http://keycloak:12800/realms/svacer/protocol/openid-connect/token"
  sign_out: "http://oauth_proxy:4180/oauth2/sign_out?rd=/oauth2/sign_in"
  tokens:
   - claims:
      subject: preferred_username
      role: svacer_role
      first_name: given_name
      second_name: second_name
      last_name: family_name
      email: email
     sign:
      - key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvR/zIW/acyWFVSuSD/8iDM3epguHljKZkaB4ITojRwisXNcn6S0ArlI8v69qV1tBFi+RH3Ys4L5Pj+xDFlemlml6wPp5X0tcD2Gax51KHqQcFjViBGVSqJUdts/bkvfiIfZLkurybkhR0ALToWvbNyD7>
        name: rsa

В секции используются следующие поля:

Название Описание
enabled Использовать OIDC провайдер. Значение false отключает данный функционал
debug Выводить в логи сервера дополнительные отладочные сообщения. Полезно при первичной настройке, в дальнейшем желательно установить в значение false
oauth_proxy.enabled Использовать утилиту oauth2-proxy в качестве механизма поддержки протокола OIDC. На текущий момент это единственная реализация поддержки OIDC протокола
oauth_proxy.clock Допускаемая погрешность расхождения времени между сервером аутентификации и клиентом. Указывается значение в минутах
oauth_proxy.sign_in Точка входа сервера OAuth2 для получения токена. Используется в Svacer только для работы CLI команд и сервисной учетной записи. При некорректном значении работа клиента Svacer с сервером Svacer через OIDC будет невозможна, но при правильной настройке других параметров, в GUI пользователи работать смогут
oauth_proxy.sign_out Ссылка, которая будет использована при выходе пользователя из системы (logout в GUI). Более подробно см. Выход пользователя из системы
oauth_proxy.tokens Массив объектов (token), описывающих структуру JWT токена OIDC сервера и данные, необходимые для проверки выпускаемого им токена
token.claims Описывает структуру токена. Поля этой сущности определяют свойства создаваемого внутреннего пользователя Svacer и его права
token.claims.subject Название поля из Claims токена, значение которого будет использовано для заполнения свойства Логин у созданного пользователя Svacer
token.claims.first_name Название поля из Claims токена, значение которого будет использовано для заполнения свойства Имя у созданного пользователя Svacer
token.claims.second_name Название поля из Claims токена, значение которого будет использовано для заполнения свойства Отчество у созданного пользователя Svacer
token.claims.last_name Название поля из Claims токена, значение которого будет использовано для заполнения свойства Фамилия у созданного пользователя Svacer
token.claims.email Название поля из Claims токена, значение которого будет использовано для заполнения свойства E-Mail у созданного пользователя Svacer
token.claims.role Название поля из Claims токена, значение которого будет использовано для добавления роли пользователю Svacer. Значение должно быть именем уже существующей роли или значением "admin" для добавления роли администратора. Автоматическое назначение роли происходит только при первом создании пользователя
token.sign Содержит данные, необходимые для проверки подписи JWT токена
token.sign.key Открытый ключ, используемый OIDC сервером для проверки токена. Формат: BASE64(ASN1.DER)
token.sign.name Имя алгоритма ЭЦП. Поддерживаются: RSA, ECDSA

Конфигурация OAuth2-proxy

Конфигурация OAauth2-proxy может выполнятся через параметры CLI, через указание параметров в конфигурационном файле, а также через переменные окружения. Названия параметров, передаваемых в CLI, в конфигурационном файле и через переменные окружения находятся в следующем соответствии друг с другом (на примере параметра client_secret):

Конфигурационный файл CLI Переменная окружения
client_secret --client-secret OAUTH2_PROXY_CLIENT_SECRET

Для нормальной работы желательно наличие DNS имен для хостов (OAuth2-proxy использует Cookies для хранения там информации о сессии аутентификации пользователя а также для хранения csrf токена).

Ниже приводится пример конфигурации oauth2-proxy для подключения Svacer сервера к OAuth2 серверу Keycloak

standard_logging = true
standard_logging_format = "[{{.Timestamp}}] [{{.File}}] {{.Message}}"
auth_logging = true
auth_logging_format = "{{.Client}} - {{.Username}} [{{.Timestamp}}] [{{.Status}}] {{.Message}}"
pass_user_headers = true
pass_host_header = true
email_domains = [
 "*"
]
client_id = "svacer-auth-proxy"
client_secret = "q2rNKGofxpw7FzmZDstSIyNNyzkW1BsW"
pass_access_token = true
cookie_name = "_oauth2_proxy2"
cookie_secret = "2-W9DDrnlfBEK75F3zGpszuwTSqwBcUFQm6OQa3dHgU="
cookie_expire = "11m"
cookie_refresh = "10m"
cookie_secure = false
provider = "keycloak-oidc"
show_debug_on_error = true
cookie_csrf_per_request = true
cookie_csrf_expire = "36h"
skip_auth_routes = ["GET=/static/.*","/api/public/*","GET=/api/auth_settings"]

В файле выше указаны не все требуемые параметры для нормальной работы OAuth2-proxy. Ниже приведены наиболее важные параметры конфигурационного файла OAuth2-proxy с пояснениями

Название Описание
client_id Название клиента (в терминах OAuth2), от имени которого пользователь будет аутентифицироваться на сервере OAuth
client_secret Секрет клиента (в терминах OAuth2)
pass_access_token Передавать токен доступа от Oauth2 сервера в Svacer (через заголовки). Данный токен будет использован сервером Svacer для идентификации и аутентификации пользователя, а также для получения первоначальной информации о нем
provider Имя провайдера OAuth2
cookie_csrf_per_request Возможность отправки нескольких запросов одновременно
skip_auth_routes Указывается список запросов, которые не требуют аутентификации. Для корректной работы Svacer необходимо указать значения из примера выше
http_address Имя хоста, на котором будет работать OAuth2-proxy, см. пример в разделе Конфигурация в Docker
upstreams Хост, на котором работает Svacer, см. пример в разделе Конфигурация в Docker
redirect_url URL на который будет осуществлено перенаправление после успешной аутентификации на OAuth2 сервере, см. пример в разделе Конфигурация в Docker
oidc_issuer_url URL сервера OAuth2 для начала аутентификации, см. пример в разделе Конфигурация в Docker. С помощью данного URL будет получен список точек входа для поддержки разных потоков аутентификации (в терминах OAuth2)

Детали работы OAuth2-proxy с куками и токенами

Для корректной настройки OAuth2-proxy полезно понимать детали работы OAath2-proxy. На шаге 2 прокси определяет необходимость выполнения аутентификации пользователя. Прокси проверяет наличие куки _oauth2_proxy и его срок действия. Срок действия создаваемых кук указывается в поле cookie_expire. Если срок действия куки закончен, то пользователь будут перенаправлен на точку входа прокси: /oauth2/sign_in.

Важным полем конфигурации является поле cookie_refresh. При каждом запросе прокси обновляет свои куки с периодичностью, указанной в cookie_refresh. Вместе с обновлением своих куки прокси проверяет состояние сессии на OAuth2 сервере и получает новый токен доступа. То есть, если в поле cookie_refresh стоит значение 1 минута, 1 раз в минуту (если пользователь отправляет запросы 1 раз в 10 секунд, то каждый 6 запрос будет обновлять куки прокси) OAuth2-proxy будет обновлять свои куки _oauth2_proxy и обновлять состоянии сессии аутентификации на сервере OAuth2 с получением токена доступа. Если сессия OAuth2 завершена, пользователь будет перенаправлен на точку входа аутентификации сервера OAuth2.

Выход пользователя из системы

Процедура выхода пользователя из Svacer состоит из двух этапов. На первом этапе производится инвалидация токена Svacer, далее осуществляется переход по ссылке указанной в параметре oauth_proxy.sign_out с тем, чтобы прокси сервер или/и OAuth2 сервер смогли выполнить инвалидацию сущностей аутентификации, выданных пользователю. Явным признаком корректной работы выхода пользователя из системы является отсутствие данных аутентификации в куках сервера OAuth2 (и/или прокси) после выхода пользователя из системы.

Работа со Svacer через CLI

Работа в CLI происходит через специальную учетную запись в OAuth2 сервере, которая не требует аутентификации пользователя через web форму. Для этой цели используется Client Credentials Flow из спецификации OAuth2. На OAuth2 сервере требуется создание пары client@secret и настройки правил формирования JWT токена, соответствующего настройкам OIDC в Svacer. Наиболее важным моментом является наличие такого поля в Claims токена, которое было указано в конфигурации Svacer, в поле token.claims.subject. После успешного входа на сервер Svacer, будет создан локальный пользователь Svacer, соответствующий субъекту токена OAuth2. Пользователю также будет назначена роль, указанная в token.claims.role, если она будет найдена. По этой причине рекомендуется перед первым использованием Svacer совместно с сервером OIDC настроить роли в Svacer.

Процесс аутентификации пользователя CLI в Svacer с использованием OIDC сервера происходит следующим образом:

  1. Клиент запрашивает настройки сервера Svacer (по этой причине /api/settings должен проходить через прокси без аутентификации)
  2. В полученных настройках считывается значение, соответствующее полю oauth_proxy.sign_in
  3. Полученная на втором этапе ссылка, используется для получения токена доступа от сервера OAuth2
  4. Полученный на 3 шаге токен, обменивается на токен Svacer, с помощью запроса: POST /api/public/oidc/login. Данный запрос должен быть включен в список запросов, не требующих аутентификации (см. пример конфигурации OAuth2-proxy)

В виду всего вышесказанного, в конфигурационном файле OAuth2-proxy надо делать исключения на

  • запрос /api/public/oidc/login (иначе прокси будет пытаться аутентифицировать их, выдавая веб форму для аутентификации пользователя)
  • запрос /api/settings

Возможные проблемы при настройке

Сообщение 'Cookies not found'

Проблема в DNS имена хоста Keycloak. Проблема встречается когда хост Keycloak имеет разные имена или в некоторых случаях обращение к нему происходит по IP адресу.

Сообщение 'Invalid parameter: redirect_url'

При перенаправлении пользователя на Keycloak сервер, OAuth2-proxy передал неверное значение в параметре redirect_uri. Необходимо проверить, что в настройках Keycloak и в параметре redirect_uri OAauth2-proxy находятся одинаковые значения

Сообщение 'CSRF cookie failed validation'

Данная ошибка появляется по следующим причинам:

  • csrf токен не найден в куках; Можно открыть консоль разработчика и убедится, что в куках для хоста oauth2-proxy есть кука: _oauth2_proxy_csrf_XXXXX
  • csrf токен истек; Для решения проблемы можно увеличить время действия csrf токена (см. Конфигурация OAuth2-proxy)
  • был произведен перезапуск oauth2-proxy, а строка адреса в URL осталась от предыдущего запуска; Попробовать начать процедуру входа снова, перейдя на главную страницу OAuth2-proxy

Строка переключения языка GUI Svacer и белый экран.

Сервер Svacer недоступен.

При работе с CLI возникает ошибка: 'Failed to query server. Details: server response error: 403'

Не прописано исключение для запроса: /api/public/server/info

При работе с CLI возникает ошибка: 'Cannot get authentication settings from server StatusCode: 403'

Не прописано исключение для запроса: /api/auth_settings

При работе с CLI возникает ошибка: 'ERROR: invalid character '<' looking for beginning of value'

Не прописано исключение для запроса: /api/public/oidc/login

Конфигурация в Docker

Ниже приводятся примеры конфигурации контейнеров для запуска Svacer в тестовом режиме с целью понимания логики работы oauth2-proxy совместно со Svacer и сервером Keycloak.

Образы Docker

Svacer

Файл Dockerfile:

FROM ubuntu:22.04

LABEL maintainer="akuzmin@ispras.ru"

ARG DEBIAN_FRONTEND=noninteractive

RUN apt update && apt install -y --no-install-recommends curl \
    && rm -rf /var/cache/apt/archives /var/lib/apt/lists/* \
    && mkdir -p /svacer/bin && mkdir -p /svacer/store 

COPY svacer/bin/svacer-server /svacer/bin/
COPY svacer/bin/svacer /svacer/bin/

WORKDIR /svacer/bin

ENV STORE=/svacer/store
ENV SVACER_PG_URL=postgres://svace:svace@127.0.0.1:5432/svace
ENV MEMSETTINGS=default
ENV PATH=/svacer/bin:$PATH

EXPOSE 8080

CMD /svacer/bin/svacer-server --memsettings=${MEMSETTINGS} run --store $STORE --pg $SVACER_PG_URL --config /config/config.yaml

OAuth2-proxy

Файл Dockerfile:

FROM ubuntu:22.04
LABEL maintainer="chernykov_sv@ispras.ru"
RUN mkdir /config
RUN mkdir /logs
#COPY oauth.cfg oauth.cfg
WORKDIR /oauth
COPY oauth2-proxy oauth2-proxy
COPY start.sh start.sh
RUN apt update && apt install curl -y
ENTRYPOINT ["/bin/bash", "-c", "/oauth/start.sh"]

Скрипт start.sh (полезен для определения факта запуска Keycloak контейнера):

#!/bin/bash
exit='no'
start='no'
tmt=60
echo "Using $KEYCLOAK_HOST"
until [[ $exit == 'yes' ]]; do
  sleep 5
  tmt=$(($tmt-5))
  if [[ $tmt == 0 ]]; then
    exit='yes'
  fi

  resp=`curl --head -fsS  http://$KEYCLOAK_HOST/health/ready`
  if [[ $? == 0 ]]; then
    exit='yes'
    start='yes'
  fi

done
if [[ $start == 'yes' ]]; then
echo 'Starting oauth...'
./oauth2-proxy --config /config/oauth.cfg --logging-filename /logs/oauth.log
else
 echo "Keycloak is not ready ...Can not start oauth2_proxy"
fi

Docker-compose

Файл docker-compose.yml

version: "3.6"
services:
  oauth_proxy:
    image: oauth_proxy
    container_name: oauth_proxy
    environment:
      - OAUTH2_PROXY_HTTP_ADDRESS=http://oauth_proxy:8080
      - OAUTH2_PROXY_UPSTREAMS=http://svacer:8080
      - OAUTH2_PROXY_REDIRECT_URL=http://oauth_proxy:4180/oauth2/callback
      - OAUTH2_PROXY_OIDC_ISSUER_URL=http://keycloak:8888/realms/svacer
      - KEYCLOAK_HOST=keycloak:8888
    volumes:
      - ./config/proxy:/config
      - ./logs:/logs

    depends_on:
      svacer:
          condition: service_healthy
    ports:
      - "4180:8080"
    networks:
      svacer_oauth:
        ipv4_address: 10.10.10.2

  postgresql:
    image: postgres:12.16
    container_name: oauth_postgres
    restart: always
    shm_size: 1g
    environment:
      - POSTGRES_DB=svace
      - POSTGRES_USER=svace
      - POSTGRES_PASSWORD=svace
      - POSTGRES_ROOT_PASSWORD=svace
    expose:
      - "5432"
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    networks:
      svacer_oauth:
         ipv4_address: 10.10.10.3
    healthcheck:
      test: pg_isready -U svace
      interval: 8s
      start_period: 16s
      timeout: 4s
      retries: 4

  keycloak:
    image: keycloak:latest
    container_name: oauth_keycloak
    environment:
      - KEYCLOAK_ADMIN=admin
      - KEYCLOAK_ADMIN_PASSWORD=1234
      - KEYCLOAK_LOGLEVEL=TRACE
      - KC_HEALTH_ENABLED=true
    command: 
      - start-dev
      - --import-realm
      - --http-port=8888
    volumes:
      - ./keycloak_realm:/opt/keycloak/data/import
    ports:
      - "8888:8888"
    expose:
      - "8888"
    networks:
      svacer_oauth:
         ipv4_address: 10.10.10.3
    healthcheck:
      test: pg_isready -U svace
      interval: 8s
      start_period: 16s
      timeout: 4s
      retries: 4

  svacer:
    image: oauth_svacer:latest
    container_name: oauth_svacer
    restart: always
    shm_size: 1g
    depends_on:
      postgresql:
        condition: service_healthy
    ports:
      - "3002:3002"
      - "18080:8080"
    volumes:
      - ./svacer_data:/data
      - ./config/svacer/:/config
    environment:
      - SVACER_PG_URL=postgres://svace:svace@postgresql:5432/svace
      - SVACER_DEBUG=true
      - SVACER_OPT='--config /config/oidc3.yaml'
      - STORE=/data/store
    networks:
      svacer_oauth:
         ipv4_address: 10.10.10.5
    healthcheck:
      test: curl --fail http://localhost:8080/api/health || exit 1
      interval: 8s
      start_period: 16s
      timeout: 4s
      retries: 4

networks:
  svacer_oauth:
    driver: bridge
    ipam:
      config:
        - subnet: 10.10.10.0/24
          gateway: 10.10.10.1