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

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, landing page, корпоративні сайти, онлайн каталоги, квіз, промо-сайти, блоги, ресурси новин, інформаційні портали, форуми, агрегатори
Сайти або веб-програми електронної комерції
Інтернет-магазини, B2B-портали, маркетплейси, онлайн-обмінники, кешбек-сайти, біржі, дропшиппінг-платформи, парсери товарів
Веб-програми для управління бізнес-процесами
CRM-системи, ERP-системи, корпоративні портали, системи управління виробництвом, парсери інформації
Сайти або веб-програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, конструктори сайтів, портали надання електронних послуг, відеохостинги, тематичні портали

Це лише деякі з технічних типів сайтів, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Пропоновані послуги
Показано 1 з 1 послугУсі 2065 послуг
Реалізація аутентифікації та авторизації на рівні API Gateway
Складна
~3-5 робочих днів
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    874
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851

Реалізація аутентифікації та авторизації на рівні 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 днів.