Ответ
В микросервисах авторизация строится вокруг принципа единого входа (SSO) и передачи контекста пользователя между сервисами, обычно с использованием токенов.
Базовая архитектура:
- Сервис аутентификации (Identity Provider - IdP): Отдельный микросервис (например, на базе IdentityServer, Keycloak или Azure AD), отвечающий за логин, выдачу и валидацию токенов.
- API Gateway: Единая точка входа, которая часто берет на себя первичную проверку токена (валидация подписи, срока жизни).
- Микросервисы: Получают проверенный токен и извлекают из него данные для авторизации (claims).
Детали реализации в .NET-экосистеме:
1. Выбор и валидация токена:
- JWT (JSON Web Token): Самый популярный выбор. Микросервис проверяет подпись токена с помощью публичного ключа от IdP.
- Настройка в микросервисе:
services.AddAuthentication("Bearer") .AddJwtBearer(options => { options.Authority = "https://auth.mycompany.com"; // Адрес IdP options.Audience = "orders-api"; // Имя ресурса (ресурсного сервера) // Валидация происходит автоматически через метаданные с Authority });
2. Передача контекста и авторизация внутри сервиса:
- После аутентификации
HttpContext.Userзаполняется claims из токена. -
Авторизация делается на основе этих claims:
// Проверка роли (если роль передается как claim) [Authorize(Roles = "Admin,Manager")] public IActionResult GetConfidentialData() { ... } // Проверка кастомного claim [Authorize(Policy = "MustBeFromDepartmentX")] public IActionResult GetDepartmentData() { ... }// Регистрация политики в Program.cs services.AddAuthorization(options => { options.AddPolicy("MustBeFromDepartmentX", policy => policy.RequireClaim("department", "X")); });
3. Продвинутые сценарии и проблемы:
- Проблема: Частая валидация токена по сети (introspection) или запрос публичного ключа создает нагрузку на IdP и задержки.
- Решение: Кеширование. Кешировать публичные ключи (JWKS) и результаты интроспекции на уровне микросервиса или API Gateway.
- Проблема: Токену нужны права для вызова других микросервисов (цепочка вызовов).
- Решение:
- Delegation / On-behalf-of flow (OBO): Первый сервис может обменять свой токен на новый, предназначенный для вызова второго сервиса, с теми же или уменьшенными правами.
- Передача исходного токена: Более просто, но менее безопасно — передавать исходный токен дальше по цепочке.
4. Паттерн Sidecar для единообразия: Чтобы не дублировать код аутентификации в каждом сервисе, можно вынести его в sidecar-контейнер (например, Envoy Proxy), который будет прозрачно проверять токены перед передачей запроса основному сервису.
5. Безопасность на уровне сообщений (для событий):
В event-driven архитектуре вместе с сообщением (event) также необходимо передавать контекст безопасности (например, User-Id или Authorization заголовок), чтобы сервис-подписчик мог проверить права на обработку этого события.
Итоговая рекомендация: Начинайте с простой схемы (JWT + валидация в каждом сервисе), а по мере роста вводите кеширование, API Gateway и, возможно, sidecar для централизации инфраструктурных concerns.