Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Аутентификация и авторизация
authentication

Аутентификация и авторизация

Плагины аутентификации: Key Auth, JWT, OAuth2, OIDC, LDAP

Аутентификация и авторизация в Kong

Kong предоставляет множество плагинов для аутентификации (кто пользователь?) и авторизации (что ему разрешено?).

#1. Key Auth — простейшая аутентификация

Проблема: Нужна простая аутентификация по API-ключу без сложных протоколов.

Решение: Плагин key-auth проверяет наличие API-ключа и связывает запрос с Consumer.

#1.1. Настройка key-auth

# Включение плагина глобально curl -X POST http://localhost:8001/plugins \ --data "name=key-auth" # Или на конкретный Route curl -X POST http://localhost:8001/routes/api-route/plugins \ --data "name=key-auth"

#1.2. Создание Consumer с API-ключом

# Создание Consumer curl -X POST http://localhost:8001/consumers \ --data "username=mobile-app" # Создание API-ключа для Consumer curl -X POST http://localhost:8001/consumers/mobile-app/key-auth \ --data "key=secret-key-123"

#1.3. Использование API-ключа

Проблема: Клиент должен передать API-ключ в запросе.

Решение: Ключ передаётся в заголовке, query-параметре или теле запроса.

# В заголовке (по умолчанию) curl http://localhost:8000/api/users \ -H "apikey: secret-key-123" # В query-параметре curl http://localhost:8000/api/users?apikey=secret-key-123 # В теле запроса (POST/PUT) curl -X POST http://localhost:8000/api/users \ -d "apikey=secret-key-123" \ -d "name=John"

Ответы Kong:

  • ✅ Ключ верный → запрос проксируется на upstream
  • ❌ Ключ отсутствует → 401 Unauthorized: No API key found in request
  • ❌ Ключ неверный → 401 Unauthorized: Invalid API key

#1.4. Кастомизация key-auth

Проблема: Нужно изменить имя параметра или место поиска ключа.

Решение: Конфигурация плагина.

curl -X POST http://localhost:8001/routes/api-route/plugins \ --data "name=key-auth" \ --data "config.key_names[]=X-API-Key" \ --data "config.key_in_header=true" \ --data "config.key_in_query=false" \ --data "config.key_in_body=false" \ --data "config.hide_credentials=true"

Параметры:

  • key_names — имена параметров/заголовков для поиска ключа
  • key_in_header — искать в заголовках (по умолчанию true)
  • key_in_query — искать в query-параметрах (по умолчанию true)
  • key_in_body — искать в теле запроса (по умолчанию true)
  • hide_credentials — удалять ключ из запроса перед проксированием (по умолчанию false)

#2. JWT Authentication

Проблема: Нужна Stateless аутентификация с токенами, которые можно верифицировать без обращения к базе данных.

Решение: Плагин jwt проверяет подпись JWT-токена и извлекает claims.

#2.1. Настройка jwt-auth

# Включение плагина curl -X POST http://localhost:8001/plugins \ --data "name=jwt"

#2.2. Создание JWT credentials

Проблема: Consumer нужен JWT credentials для генерации токенов.

Решение: Создание credentials с алгоритмом подписи.

#HS256 (симметричное шифрование)

# Создание Consumer curl -X POST http://localhost:8001/consumers \ --data "username=mobile-app" # Создание JWT credentials с HS256 curl -X POST http://localhost:8001/consumers/mobile-app/jwt \ --data "algorithm=HS256" \ --data "key=mobile-app-key" \ --data "secret=my-super-secret-key"

Важно: key — это iss (issuer) или kid (key id) в токене. secret — секретный ключ для подписи.

#RS256 (асимметричное шифрование)

# Генерация ключей openssl genrsa -out jwt_private.key 2048 openssl rsa -in jwt_private.key -pubout -out jwt_public.key # Создание JWT credentials с RS256 curl -X POST http://localhost:8001/consumers/mobile-app/jwt \ --data "algorithm=RS256" \ --data "key=mobile-app-key" \ --data "rsa_public_key=$(cat jwt_public.key)"

Важно: Приватный ключ хранится у авторизационного сервера (генерирует токены), публичный — в Kong (верифицирует токены).

#2.3. Генерация JWT токена

Проблема: Клиенту нужен валидный JWT токен.

Решение: Генерация токена с правильной структурой.

#Структура JWT

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJtb2JpbGUtYXBwLWtleSIsImV4cCI6MTcwMDAwMDAwMH0.signature
   ↓                              ↓                              ↓
Header (алгоритм)           Payload (claims)              Signature

#Генерация токена (Python)

import jwt import time secret = "my-super-secret-key" payload = { "iss": "mobile-app-key", # Должен совпадать с 'key' в credentials "iat": int(time.time()), "exp": int(time.time()) + 3600, # 1 час "sub": "user-123", # Идентификатор пользователя "name": "John Doe" } token = jwt.encode(payload, secret, algorithm="HS256") print(token)

#Генерация токена (OpenSSL + bash)

# Для RS256 HEADER='{"alg":"RS256","typ":"JWT"}' PAYLOAD='{"iss":"mobile-app-key","exp":1700000000,"sub":"user-123"}' HEADER_B64=$(echo -n $HEADER | openssl base64 -e -A) PAYLOAD_B64=$(echo -n $PAYLOAD | openssl base64 -e -A) SIGNATURE=$(echo -n "$HEADER_B64.$PAYLOAD_B64" | \ openssl dgst -sha256 -sign jwt_private.key | \ openssl base64 -e -A | tr '+/' '-_' | tr -d '=') TOKEN="$HEADER_B64.$PAYLOAD_B64.$SIGNATURE" echo $TOKEN

#2.4. Использование JWT токена

# В заголовке Authorization (рекомендуется) curl http://localhost:8000/api/users \ -H "Authorization: Bearer <jwt-token>" # В query-параметре curl http://localhost:8000/api/users?jwt=<jwt-token>

#2.5. Валидация claims

Проблема: Нужно проверять дополнительные claims (например, expiration).

Решение: Конфигурация плагина jwt.

curl -X POST http://localhost:8001/plugins \ --data "name=jwt" \ --data "config.key_claim_name=iss" \ --data "config.claims_to_verify=exp" \ --data "config.secret_is_base64=false" \ --data "config.run_on_preflight=true"

Параметры:

  • key_claim_name — claim, который содержит identifier (по умолчанию iss)
  • claims_to_verify — список claims для проверки (exp — expiration)
  • secret_is_base64 — если secret в base64
  • run_on_preflight — проверять JWT для OPTIONS запросов

#2.6. Извлечение Consumer из JWT

Проблема: Нужно связать JWT токен с Consumer в Kong.

Решение: Kong автоматически извлекает Consumer по claim iss (или key_claim_name).

# Если токен содержит {"iss": "mobile-app-key"} # Kong найдёт JWT credentials с key="mobile-app-key" # и свяжет запрос с Consumer "mobile-app"

Для кастомной логики используйте claim sub:

# Токен содержит {"sub": "user-123"} # Можно использовать в кастомном плагине: local credential = kong.client.get_credential() local user_id = credential.sub -- "user-123"

#3. OAuth2 — полноценная авторизация

Проблема: Нужна поддержка OAuth2 flow для сторонних приложений.

Решение: Плагин oauth2 предоставляет OAuth 2.0 сервер авторизации.

#3.1. Настройка oauth2

curl -X POST http://localhost:8001/plugins \ --data "name=oauth2" \ --data "config.scopes[]=read" \ --data "config.scopes[]=write" \ --data "config.enable_authorization_code=true" \ --data "config.enable_client_credentials=true" \ --data "config.enable_password_grant=true" \ --data "config.enable_implicit_grant=false" \ --data "config.token_expiration=7200" \ --data "config.mandatory_scope=true"

Grant types:

  • authorization_code — для веб-приложений (redirect на callback URL)
  • client_credentials — для machine-to-machine (нет пользователя)
  • password — для trusted clients (пользователь вводит credentials)
  • implicit — устарел, не рекомендуется (токен в URL)

#3.2. Создание OAuth2 Consumer

# Создание Consumer curl -X POST http://localhost:8001/consumers \ --data "username=web-app" # Создание OAuth2 credentials curl -X POST http://localhost:8001/consumers/web-app/oauth2 \ --data "name=My Web App" \ --data "client_id=web-app-client-id" \ --data "client_secret=web-app-secret" \ --data "redirect_uris[]=https://app.example.com/callback"

#3.3. Authorization Code Flow

Проблема: Веб-приложение должно получить токен через redirect.

Решение: OAuth2 authorization code flow.

#Шаг 1: Redirect на Kong для авторизации

GET /oauth2/authorize?
  client_id=web-app-client-id&
  response_type=code&
  scope=read write&
  redirect_uri=https://app.example.com/callback

Ответ: Kong перенаправляет на redirect_uri с кодом:

https://app.example.com/callback?code=AUTH_CODE

#Шаг 2: Обмен кода на токен

curl -X POST http://localhost:8000/oauth2/token \ -d "grant_type=authorization_code" \ -d "code=AUTH_CODE" \ -d "client_id=web-app-client-id" \ -d "client_secret=web-app-secret" \ -d "redirect_uri=https://app.example.com/callback"

Ответ:

{ "access_token": "ACCESS_TOKEN", "token_type": "bearer", "expires_in": 7200, "refresh_token": "REFRESH_TOKEN", "scope": "read write" }

#Шаг 3: Использование токена

curl http://localhost:8000/api/users \ -H "Authorization: Bearer ACCESS_TOKEN"

#3.4. Client Credentials Flow

Проблема: Machine-to-machine аутентификация без пользователя.

Решение: OAuth2 client credentials grant.

curl -X POST http://localhost:8000/oauth2/token \ -d "grant_type=client_credentials" \ -d "client_id=web-app-client-id" \ -d "client_secret=web-app-secret" \ -d "scope=read"

Ответ:

{ "access_token": "ACCESS_TOKEN", "token_type": "bearer", "expires_in": 7200 }

#4. OpenID Connect (OIDC)

Проблема: Нужна аутентификация через внешний провайдер (Google, Auth0, Okta).

Решение: Плагин openid-connect для интеграции с OIDC провайдерами.

#4.1. Настройка openid-connect

Проблема: Нужно подключить Kong к внешнему OIDC провайдеру.

Решение: Конфигурация плагина с issuer и credentials.

curl -X POST http://localhost:8001/plugins \ --data "name=openid-connect" \ --data "config.issuer=https://accounts.google.com" \ --data "config.client_id=your-google-client-id" \ --data "config.client_secret=your-google-client-secret" \ --data "config.redirect_uri=https://api.example.com/callback" \ --data "config.scopes=openid profile email" \ --data "config.response_type=code" \ --data "config.token_endpoint_auth_method=client_secret_post" \ --data "config.logout_query_arg_name=logout" \ --data "config.logout_redirect_uri=https://app.example.com/logged-out"

#4.2. Flow работы

  1. Пользователь запрашивает защищённый ресурс
  2. Kong перенаправляет на OIDC провайдер (Google)
  3. Пользователь авторизуется у провайдера
  4. Провайдер redirect обратно в Kong с authorization code
  5. Kong обменивает code на ID token + access token
  6. Kong извлекает информацию о пользователе из ID token
  7. Запрос проксируется на upstream с информацией о пользователе

#4.3. Извлечение информации о пользователе

Проблема: Бэкенд должен знать, кто пользователь.

Решение: Kong добавляет заголовки с claims из ID token.

# Заголовки, которые добавляет Kong: X-Consumer-Username: <sub из ID token> X-Consumer-Id: <consumer id в Kong> Authorization: Bearer <access token>

Для кастомных заголовков:

curl -X POST http://localhost:8001/plugins \ --data "name=openid-connect" \ --data "config.authenticated_user_claim=email" \ --data "config.set_access_token_header=true" \ --data "config.set_id_token_header=true" \ --data "config.set_refresh_token_header=false"

#5. LDAP Authentication

Проблема: Нужна аутентификация через корпоративный LDAP/Active Directory.

Решение: Плагин ldap-auth.

#5.1. Настройка ldap-auth

curl -X POST http://localhost:8001/plugins \ --data "name=ldap-auth" \ --data "config.ldap_host=ldap.example.com" \ --data "config.ldap_port=389" \ --data "config.base_dn=dc=example,dc=com" \ --data "config.attribute=uid" \ --data "config.start_tls=false" \ --data "config.verify_ldap_host=true" \ --data "config.header_type=Basic"

#5.2. Использование

# Basic Auth с LDAP credentials curl http://localhost:8000/api/users \ -H "Authorization: Basic $(echo -n 'username:password' | base64)"

Kong проверяет credentials против LDAP сервера.

#6. ACL — авторизация по группам

Проблема: Нужно ограничить доступ к API для определённых групп пользователей.

Решение: Плагин acl работает в паре с плагином аутентификации.

#6.1. Настройка ACL

# Включение плагина acl curl -X POST http://localhost:8001/routes/admin-route/plugins \ --data "name=acl" \ --data "config.allow[]=admin" \ --data "config.allow[]=manager" \ --data "config.hide_groups=true"

#6.2. Добавление Consumer в группы

# Создание Consumer curl -X POST http://localhost:8001/consumers \ --data "username=john" # Добавление в группу admin curl -X POST http://localhost:8001/consumers/john/acl \ --data "group=admin" # Добавление в группу manager curl -X POST http://localhost:8001/consumers/jane/acl \ --data "group=manager"

#6.3. Flow работы

1. Пользователь аутентифицируется (key-auth/jwt/oauth2)
       ↓
2. Kong извлекает Consumer
       ↓
3. Плагин acl проверяет, состоит ли Consumer в разрешённых группах
       ↓
4. Если да → запрос проксируется
   Если нет → 403 Forbidden

#7. Комбинирование плагинов аутентификации

Проблема: Нужна поддержка нескольких методов аутентификации.

Решение: Применение нескольких плагинов к одному Route.

# Key-auth для внутренних сервисов curl -X POST http://localhost:8001/routes/internal/plugins \ --data "name=key-auth" # JWT для мобильных приложений curl -X POST http://localhost:8001/routes/mobile/plugins \ --data "name=jwt" # OAuth2 для партнёров curl -X POST http://localhost:8001/routes/partners/plugins \ --data "name=oauth2" # Глобальный ACL для админских endpoints curl -X POST http://localhost:8001/routes/admin/plugins \ --data "name=acl" \ --data "config.allow[]=admin"

#8. Best Practices

#8.1. Безопасность

  • Используйте RS256 для JWT — приватный ключ не передаётся
  • Включите claims_to_verify=exp — проверка expiration
  • Короткий срок жизни токенов — 1-2 часа для access token
  • Используйте refresh tokens — для обновления access token
  • HTTPS обязательно — токены не должны передаваться по HTTP

#8.2. Производительность

  • Кэшируйте JWT credentials — Kong кэширует автоматически
  • Используйте Redis для OAuth2 токенов — вместо базы данных
  • Избегайте частых перевыпусков токенов — используйте refresh

#8.3. Мониторинг

# Проверка количества выданных токенов curl http://localhost:8001/oauth2/tokens # Отзыв токена curl -X DELETE http://localhost:8001/oauth2/tokens/{token-id}

Далее: Rate Limiting и защита API