Реализация аутентификации и авторизации на уровне API Gateway

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.
Разработка и обслуживание любых видов сайтов:
Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация аутентификации и авторизации на уровне API Gateway
Сложная
~3-5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1214
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    852
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1041
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    823
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    815

Реализация аутентификации и авторизации на уровне API Gateway

Вынос аутентификации и авторизации в API Gateway позволяет разгрузить микросервисы от повторяющейся логики проверки токенов. Сервисы получают только проверенные запросы с уже извлечёнными claims.

Схема работы

Client → [API Gateway: validate JWT, extract claims] → Service
                                                         ↑
                                      X-User-ID, X-Role, X-Tenant headers

Сервисы доверяют заголовкам от Gateway и не делают собственную JWT-валидацию. Внешний доступ к сервисам напрямую — закрыт через сетевые политики.

JWT валидация в Kong

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

# Создать consumer и credentials
curl -X POST http://localhost:8001/consumers \
  -d "username=frontend-app"

curl -X POST http://localhost:8001/consumers/frontend-app/jwt \
  -d "algorithm=RS256" \
  -d "rsa_public_key=$(cat /keys/public.pem)"

Клиент передаёт: Authorization: Bearer <JWT>. Kong проверяет подпись и срок действия, при ошибке возвращает 401.

OAuth 2.0 через Kong

curl -X POST http://localhost:8001/services/api/plugins \
  -d "name=oauth2" \
  -d "config.scopes[]=read" \
  -d "config.scopes[]=write" \
  -d "config.mandatory_scope=true" \
  -d "config.token_expiration=3600" \
  -d "config.enable_client_credentials=true" \
  -d "config.enable_authorization_code=true"

OIDC в APISIX

{
  "plugins": {
    "openid-connect": {
      "client_id": "api-gateway",
      "client_secret": "secret",
      "discovery": "https://keycloak.company.com/realms/myapp/.well-known/openid-configuration",
      "scope": "openid profile",
      "set_access_token_header": true,
      "set_userinfo_header": true,
      "token_signing_alg_values_expected": ["RS256"],
      "introspection_endpoint_auth_method": "client_secret_post",
      "set_id_token_header": false
    }
  }
}

Кастомный Lambda Authorizer (AWS API Gateway)

# authorizer.py
import json
import jwt
import boto3

def handler(event, context):
    token = event['authorizationToken'].replace('Bearer ', '')

    try:
        # Получить публичный ключ из AWS Secrets Manager
        secret = boto3.client('secretsmanager').get_secret_value(
            SecretId='jwt-public-key'
        )
        public_key = secret['SecretString']

        payload = jwt.decode(
            token,
            public_key,
            algorithms=['RS256'],
            audience='api.company.com'
        )

        # Проверка дополнительных прав
        if not check_permissions(payload, event['methodArn']):
            return generate_policy(payload['sub'], 'Deny', event['methodArn'])

        return generate_policy(
            payload['sub'],
            'Allow',
            event['methodArn'],
            context={
                'user_id': payload['sub'],
                'tenant_id': payload.get('tenant_id'),
                'role': payload.get('role', 'user')
            }
        )

    except jwt.ExpiredSignatureError:
        raise Exception('Token expired')
    except jwt.InvalidTokenError:
        raise Exception('Unauthorized')


def generate_policy(principal, effect, resource, context=None):
    policy = {
        'principalId': principal,
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                'Action': 'execute-api:Invoke',
                'Effect': effect,
                'Resource': resource
            }]
        }
    }
    if context:
        policy['context'] = context
    return policy


def check_permissions(payload, method_arn):
    role = payload.get('role', 'user')
    # Извлечь HTTP метод из ARN
    parts = method_arn.split(':')[-1].split('/')
    http_method = parts[2] if len(parts) > 2 else 'GET'

    if http_method in ['POST', 'PUT', 'DELETE'] and role == 'readonly':
        return False
    return True

Передача claims в upstream-сервисы

После валидации Gateway добавляет заголовки:

# Traefik ForwardAuth response headers propagation
http:
  middlewares:
    jwt-auth:
      forwardAuth:
        address: "http://auth-service:4000/validate"
        authResponseHeaders:
          - X-User-ID
          - X-User-Role
          - X-Tenant-ID
          - X-Subscription-Plan
-- Kong plugin: извлечение claims из JWT и добавление в upstream headers
local jwt_decoder = require "kong.plugins.jwt.jwt_parser"

local function execute(conf)
  local token = kong.request.get_header("authorization")
  if token then
    token = token:gsub("Bearer ", "")
    local jwt_obj = jwt_decoder:new(token)
    local claims = jwt_obj.claims

    kong.service.request.set_header("X-User-ID", claims.sub)
    kong.service.request.set_header("X-Tenant-ID", claims.tenant_id)
    kong.service.request.set_header("X-User-Role", claims.role)
  end
end

RBAC (Role-Based Access Control) на уровне Gateway

# Kong: разные consumer groups с разными правами
# Группа "admins" — полный доступ
# Группа "readonly" — только GET запросы

# ACL плагин
curl -X POST http://localhost:8001/services/admin-api/plugins \
  -d "name=acl" \
  -d "config.allow[]=admin-group" \
  -d "config.hide_groups_header=true"

# Назначить consumer в группу
curl -X POST http://localhost:8001/consumers/alice/acl \
  -d "group=admin-group"

Mutual TLS (mTLS) для service-to-service

# Kong: требовать клиентский сертификат
curl -X POST http://localhost:8001/services/internal-api/plugins \
  -d "name=mtls-auth" \
  -d "config.ca_certificates[]=$(cat ca-cert.pem)" \
  -d "config.skip_consumer_lookup=true"

Обработка refresh token

// Middleware перед Gateway: автоматическое обновление токена
async function refreshMiddleware(req, res, next) {
  const token = req.headers.authorization?.replace('Bearer ', '')
  if (isExpiringSoon(token)) {
    const newToken = await refreshAccessToken(req.cookies.refresh_token)
    res.setHeader('X-New-Token', newToken)
    req.headers.authorization = `Bearer ${newToken}`
  }
  next()
}

Срок выполнения

Настройка JWT/OIDC аутентификации с RBAC и передачей claims в сервисы — 2–3 рабочих дня. С кастомным Lambda Authorizer и mTLS — 4–5 дней.