Введение
В конце 2021 и в 2022 году платформа Ankorstore стремительно масштабировалась, обрастала командами, проектами, функционалом.
Понадобились решения для устранения очевидных дорогостоящих технических недоработок, в частности необходимости создания, сопровождения и интеграции систем аутентификации сервисов.
Так появился проект AEGIS с идеей создания простой, унифицированной системы аутентификации платформы.
Подробнее о происхождении названия AEGIS — здесь.
Технический обзор
Прежде чем переходить к техническим нюансам AEGIS, рассмотрим главные, связанные с его основами понятия.
Облачный
AEGIS создан для облачных технологий и с их применением:
- в основном на Go;
- для работы в кластере Kubernetes;
- специально для сервисной сетки на основе Envoy, такой как Istio.
Модульный
AEGIS — это не типичный монолитный API-шлюз аутентификации, а набор применяемых вместе компонентов платформы, включая прокси, агент и сервер аутентификации, а также фильтры Envoy.
- Прокси аутентификации — сердце AEGIS. Это облегченное, написанное на Go gRPC-приложение для внешней обработки фильтра Envoy ext-proc, применяемого к входному шлюзу Istio.
- Агент аутентификации — тоже облегченное HTTP-приложение на Go с общими конечными точками аутентификации для веб-приложений и обработкой потоков Oauth2 для тех же приложений.
- Сервер аутентификации — HTTP-приложение, написанное на PHP, для обслуживания внутренних и внешних потоков OAuth2 и с конечными точками набора открытых ключей JWKS.
Производительность/масштабируемость
AEGIS задуман быстрым, отказоустойчивым, легко масштабируемым.
- Прокси аутентификации используется в каждом запросе к платформе на уровне входного шлюза. Это Go-приложение без сохранения состояния: очень отказоустойчивое и легко масштабируемое, с быстрым реагированием на пики сетевого трафика.
- Агент аутентификации применяется при изменениях состояния аутентификации, например переходе от гостевого к пользовательскому. По тем же причинам этот компонент тоже создан на Go.
- Сервер аутентификации построен на PHP, модернизирован на Roadrunner.
Расширенное применение Istio/Envoy
В AEGIS задействуется наиболее востребованный функционал сервисной сетки Envoy: перехват и изменение трафика.
При таком подходе общая логика, такая как аутентификация, из приложений убирается на уровень платформы, где обрабатывается и совместно используется через механизм слушателей/фильтров Envoy.
Envoy-фильтр JWT authn
Когда логика аутентификации JWT из серверных приложений убирается, приходится кстати Envoy-фильтр JWT authn, размещаемый в дополнительных прокси-контейнерах Istio (Envoy):
![](https://cdn-images-1.medium.com/max/1000/0*sqwacSdHScv_R8Su.jpeg)
- 1 — Чтобы получить токен доступа JWT, на сервере авторизации клиентом выполняется поток OAuth2.
- 2 — Клиентом выполняется вызов к защищенной конечной точке приложения с предоставлением заголовка авторизации JWT.
- 3 — Запрос перехватывается дополнительным прокси-контейнером Envoy приложения, JWT проверяется по JWKS, извлеченному и кешированному на сервере аутентификации, и по дополнительным настраиваемым критериям: издателю, аудитории и т. д. Если проверка не пройдена, с прокси-сервера клиенту сразу отправляется ответ «401» без вызова в приложение. В противном случае запрос вместе с проверенным JWT передается в контейнер приложения.
Envoy-фильтр ext-proc
Envoy-фильтр ext-proc особенно удобен при размещении на уровне входного шлюза Istio (Envoy), когда мутации запросов и ответов делегируются внешнему gRPC-серверу, или внешнему процессору.
В этом фильтре применяется двунаправленное gRPC-соединение, при котором в Envoy, как gRPC-клиенте, выполняется потоковая передача частей запроса/ответа — заголовков, тела, трейлеров — внешнему процессору, или gRPC-серверу.
Во внешнем процессоре определяется, как изменить или прервать запрос/ответ, например поменять заголовок, тело или даже отправить немедленный ответ с конкретным кодом состояния, а затем отправить потоком обратно в Envoy для применения изменений перед передачей запроса/ответа.
То есть в gRPC-приложении имеются мутации для формирования или прерывания запросов и ответов под конкретные задачи.
![](https://cdn-images-1.medium.com/max/1000/0*X6XNSSXdCpwj6_gn.jpeg)
- 1 — Клиентом к конечной точке приложения отправляется запрос.
- 2 — Во входном шлюзе Istio с Envoy-фильтром ext-proc запрос перехватывается, и по двунаправленному gRPC-соединению его части — заголовки, тело, трейлеры — потоком передаются внешнему процессору.
- 3 — Во внешнем процессоре мутации запроса отправляются потоком обратно, они применяются в Envoy перед передачей запроса в приложение.
- 4 — Измененный запрос отправляется в приложение.
- 5 — После обработки из приложения отправляется ответ.
- 6 — Во входном шлюзе Istio с фильтром ext-proc ответ перехватывается, и по тому же двунаправленному gRPC-соединению, которое остается активным, потоком передаются части ответа: заголовки, тело, трейлеры.
- 7 — Во внешнем процессоре мутации ответа отправляются потоком обратно, они применяются в Envoy перед передачей ответа клиенту.
- 8 — Измененный ответ отправляется клиенту.
Вот простой демопроект на GitHub с ext-proc Envoy и внешним процессором Go.
Механизмы аутентификации
В AEGIS имеется два механизма аутентификации:
- Классический OAuth2 для API.
- OAuth2 с обработчиком токенов и куками для веб-приложений.
Классическая аутентификация OAuth2
В этом механизме применяется известный и надежный стандарт OAuth2.
Основное его предназначение — защита конечных точек API серверных приложений «классическим» способом за счет токенов доступа JWT, предоставляемых сервером аутентификации AEGIS во время выполнения потоков OAuth2.
Рабочий процесс:
![](https://cdn-images-1.medium.com/max/1000/0*B8viZFCGWL0kSBvV.jpeg)
- 1 — Чтобы получить токен доступа JWT, на сервере аутентификации AEGIS клиентом выполняется поток OAuth2.
- 2 — Клиентом выполняется вызов к конечной точке приложения 1, в заголовке авторизации запроса указывается токен доступа JWT.
- 3 — Во входном шлюзе Istio с Envoy-фильтром ext-proc запрос перехватывается, и по двунаправленному gRPC-соединению заголовки запроса, включая токен доступа JWT, потоком передаются в прокси аутентификации AEGIS.
- 4 — В прокси аутентификации AEGIS токен доступа JWT проверяется с помощью JWKS, кешированного на сервере аутентификации AEGIS. Если проверка не пройдена, с прокси аутентификации во фронт-прокси Envoy отправляется приказ немедленно прислать ответ «401», и без вызовов в приложение. В противном случае запрос из прокси-аутентификации передается дальше по цепочке фильтров Envoy.
- 5 — Запрос передается в под приложения 1, где токен доступа JWT проверяется фильтром JWT authn дополнительного прокси-контейнера. Если проверка не пройдена, из дополнительного контейнера Envoy сразу отправляется ошибка «401», и без вызова в приложение 1. В противном случае запрос направляется в контейнер приложения 1.
- 6 — Из приложения 1 в приложение 2 выполняется внутренний вызов, в качестве заголовка направляется токен доступа JWT, проверяемый в поде приложения 2 фильтром JWT authn дополнительного прокси-контейнера. Если проверка не пройдена, из дополнительного контейнера Envoy сразу отправляется ошибка «401» и вызов в приложение 2 не выполняется. В противном случае запрос направляется в контейнер приложения 2.
- 7 — В приложении 1 обработка завершается, отправляется ответ.
- 8 — Из входного шлюза Istio ответ передается клиенту, в этом случае прокси аутентификации AEGIS неактивен.
Преимущества этого механизма:
- Со стандартом OAuth2 больше возможностей взаимодействия с внешними клиентами.
- Серверные приложения не зависят от аутентификации: им не нужно выдавать, поддерживать или проверять токены.
- Нужно лишь считывать полезную нагрузку уже проверенного JWT для получения такого контекста аутентификации, как утверждения токена, например идентификатор пользователя.
- Если при аутентификации запрос невалиден, серверные приложения даже не вызываются: в AEGIS обрабатываются ответы «401», а ресурсы сохраняются для валидных запросов на серверной стороне.
- Серверные приложения защищены от внутренних вызовов.
Аутентификация OAuth2 с обработчиком токенов
Этот механизм аутентификации AEGIS интереснее. В нем применяются:
1) Шаблон обработчика токенов. В веб-приложениях задачи аутентификации выполняются не напрямую, а через размещаемого на стороне платформы агента аутентификации, которым для приложений согласовываются потоки OAuth2.
2) Куки, популярнейший и надежный способ переноса данных аутентификации. Чтобы воспользоваться контекстом аутентификации, нужно лишь направлять с каждым вызовом куки-файлы безопасности, получаемые веб-приложениями.
В случае с AEGIS куки-файлы безопасности:
- HTTP-безопасны, требуется HTTPS;
- только HTTP — для предотвращения скриптов на стороне клиента;
- шифрованные на стороне сервера по AES с прокси аутентификации AEGIS;
- им, по рекомендациям OWASP, требуются CSRF-токены для запросов без GET, HEAD и OPTIONS;
- в них содержатся токены доступа JWT и другая контекстная информация из потоков OAuth2.
В механизме применяется надежный OAuth2 с агентом аутентификации AEGIS, которым для веб-приложения обрабатываются потоки OAuth2.
Рабочие процессы:
Ниже упрощенно показаны наиболее важные рабочие процессы обработчика токенов AEGIS.
Проверка куки-файлов безопасности
В AEGIS имеется гостевой режим, в котором веб-приложения защищены куки-файлами безопасности, не привязанными к конкретному пользователю.
Рабочий процесс проверки куки-файлов безопасности применяется ко всем входящим запросам — и гостевым, и пользовательским, — которые содержат куки-файлы безопасности и предназначены для защищенной конечной точки приложения.
![](https://cdn-images-1.medium.com/max/1000/0*kduBI8B934rtqZx8.jpeg)
- 1 — Браузером вызывается защищенная конечная точка приложения 1, в которой применяется гостевой или пользовательский куки-файл безопасности, а также CSRF-токен для методов без GET, HEAD и OPTIONS.
- 2 — Во входном шлюзе Istio с Envoy-фильтром ext-proc запрос перехватывается, и по двунаправленному gRPC-соединению заголовки запроса потоком передаются в прокси аутентификации AEGIS, внешний процессор.
- 3 — В прокси аутентификации AEGIS CSRF-токен проверяется, закрытым ключом AES расшифровывается куки-файл безопасности, из которого извлекается и проверяется по JWKS сервера аутентификации AEGIS токен доступа JWT, добавляемый в заголовок запроса авторизации. Если какой-либо из этих этапов не пройден, браузеру сразу отправляется ответ «401». В противном случае запрос передается.
- 4 — Запрос передается в под приложения 1, где токен доступа JWT проверяется фильтром JWT authn дополнительного прокси-контейнера. Если проверка не пройдена, из дополнительного контейнера сразу отправляется ошибка «401», и без вызова контейнера приложения 1. В противном случае запрос направляется в контейнер приложения 1.
- 5 — Из приложения 1 в приложение 2 выполняется внутренний вызов, направляется заголовок с токеном доступа JWT, проверяемым в поде приложения 2 фильтром JWT authn дополнительного прокси-контейнера. Если проверка не пройдена, из дополнительного контейнера сразу отправляется ошибка «401», и без вызова контейнера приложения 2. В противном случае запрос направляется в контейнер приложения 2.
- 6 — В приложении 1 обработка завершается, отправляется ответ.
- 7 — Из входного шлюза Istio ответ передается клиенту, в этом случае прокси аутентификации AEGIS неактивен.
Вход/выход пользователя
Агент аутентификации AEGIS доступен в платформе через виртуальные сервисы Istio, поэтому на уровне платформы имеются общие конечные точки аутентификации, используемые в любом веб-приложении.
Серверные приложения в этом процессе не задействуются и остаются независимыми от аутентификации.
![](https://cdn-images-1.medium.com/max/1000/0*WXRcbY-Ta1iXp2_s.jpeg)
- 1 — При входе или выходе пользователя агенту аутентификации AEGIS из браузера отправляется запрос, в котором содержится гостевой или пользовательский куки-файл безопасности, CSRF-токен и — при попытке входа — учетные данные пользователя.
- 2 — Во входном шлюзе Istio с Envoy-фильтром ext-proc запрос перехватывается, и по двунаправленному gRPC-соединению заголовки запроса потоком передаются в прокси аутентификации AEGIS, внешний процессор.
- 3 — В прокси аутентификации AEGIS CSRF-токен при необходимости проверяется, закрытым ключом AES расшифровывается куки-файл безопасности, из которого извлекается и проверяется по JWKS сервера аутентификации AEGIS токен доступа JWT, добавляемый в заголовок запроса авторизации. Если какой-либо из этих этапов не пройден, браузеру сразу отправляется ответ «401». В противном случае запрос передается.
- 4 — Запрос, в заголовке которого содержится проверенный JWT, передается агенту аутентификации AEGIS.
- 5 — Агентом аутентификации AEGIS с сервера аутентификации AEGIS по OAuth2 запрашивается токен доступа JWT нового пользователя. При входе запрашивается токен пользователя по предоставленным учетным данным, при выходе — гостевой токен.
- 6 — Агентом аутентификации AEGIS генерируется ответ, в специальном заголовке которого содержится новый JWT.
- 7 — Во входном шлюзе Istio с Envoy-фильтром ext-proc ответ перехватывается, и по тому же двунаправленному gRPC-соединению, которое остается активным, заголовки ответа потоком передаются в прокси аутентификации AEGIS.
- 8 — В прокси аутентификации AEGIS новый JWT извлекается, шифруется по AES владельца закрытого ключа с другими контекстными данными, создается новый куки-файл безопасности и добавляется в заголовок ответа Set-Cookie. Новый CSRF-токен тоже добавляется в специальный заголовок.
- 9 — Из входного шлюза Istio ответ передается в браузер с новым куки-файлом безопасности и CSRF-токеном.
Преимущества этого механизма:
- Он опирается на популярные, надежные, защищенные куки-файлы с CSRF.
- На уровне платформы имеются общие конечные точки аутентификации агента AEGIS, применяемые в любом веб-приложении.
- Веб-приложения не зависят от аутентификации: вместо токенов, получаемых, сохраняемых или предоставляемых при вызовах, в них просто используются имеющиеся куки-файлы.
- Серверные приложения тоже не зависят от аутентификации: им не нужно выдавать, поддерживать или проверять токены, а нужно лишь считывать полезную нагрузку уже проверенного JWT для получения такого контекста аутентификации, как утверждения токена, например идентификатор пользователя и т. д.
- Если при аутентификации запрос невалиден, серверные приложения даже не вызываются: в AEGIS обрабатываются ответы «401», а ресурсы сохраняются для валидных запросов на серверной стороне.
- Серверные приложения защищены от внутренних вызовов.
Заключение
Цель AEGIS — полностью убрать задачи аутентификации с фронтенда и бэкенда и устранить технические недоработки, связанные с сопровождением нескольких систем аутентификации.
AEGIS работает на уровне платформы, поэтому его ресурсы — прокси, агент и сервер аутентификации — доступны любому приложению, запускаемому на сервисной сетке платформы. А значит, приложения с AEGIS не зависят от аутентификации и фокусируются на бизнес-логике.
Кроме классической JWT-аутентификации, в AEGIS используются куки-файлы с обработчиком токенов. Благодаря OAuth2 это один из самых надежных, безопасных и проверенных способов хранения данных аутентификации.
Что касается производительности, проверка обычных куков-файлов безопасности в AEGIS — дело нескольких микро- или миллисекунд, включая мутации запроса и ответа, для приложений такая проверка практически незаметна.
С AEGIS фокусируешься на техническом росте и главной цели — удобстве пользователей.
Читайте также:
- OpenTelemetry и Sentry - недооцененные инструменты трассировки распределенных систем на Golang
- 5 проектов Go: управление безопасностью и контейнерами, создание бэкендов
- Обзор плагинов Obsidian
Читайте нас в Telegram, VK и Дзен
Перевод статьи Jonathan Vuillemin: AEGIS — Ankorstore’s plaform authentication system