senior
Как обеспечить безопасность межсервисного взаимодействия?
Безопасность в микросервисной архитектуре — комплексная задача, включающая аутентификацию (OAuth2/JWT), шифрование (mTLS), управление секретами (Vault) и сетевые политики (Network Policies).
Пример
Клиент → API Gateway → Проверка JWT → Микросервис
│
┌───────▼───────┐
│ Keycloak / │
│ Spring Auth │
│ Server │
└───────────────┘
1. OAuth2/JWT: конфигурация Resource Server
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/actuator/health/**").permitAll()
.requestMatchers("/api/payments/**").hasAuthority("SCOPE_payments")
.anyRequest().authenticated()
)
.oauth2ResourceServer(oauth2 -> oauth2
.jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthConverter()))
)
.build();
}
private JwtAuthenticationConverter jwtAuthConverter() {
JwtAuthenticationConverter converter = new JwtAuthenticationConverter();
converter.setJwtGrantedAuthoritiesConverter(jwt -> {
Map<String, Object> realmAccess = jwt.getClaim("realm_access");
List<String> roles = (List<String>) realmAccess.get("roles");
return roles.stream()
.map(role -> new SimpleGrantedAuthority("ROLE_" + role))
.collect(Collectors.toList());
});
return converter;
}
}
2. mTLS (Mutual TLS) – взаимная аутентификация сервисов
При mTLS оба участника соединения предъявляют сертификаты. Обычно реализуется через Service Mesh (Istio):
Пример
# Istio PeerAuthentication — требовать mTLS
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: banking
spec:
mtls:
mode: STRICT
3. Передача контекста пользователя между сервисами
Пример
@Component
public class AuthTokenInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
String token = SecurityContextHolder.getContext().getAuthentication()
.getCredentials().toString();
request.getHeaders().setBearerAuth(token);
return execution.execute(request, body);
}
}
4. Защита секретов
- Хранение в HashiCorp Vault (не в переменных окружения и не в конфигурационных файлах).
- Ротация секретов (Vault поддерживает автоматическую ротацию паролей БД).
- Шифрование чувствительных данных в Kafka-сообщениях.
5. Сетевые политики (Network Policies в Kubernetes)
Пример
# Разрешить трафик к payment-service только от api-gateway и order-service
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: payment-service-policy
spec:
podSelector:
matchLabels:
app: payment-service
ingress:
- from:
- podSelector:
matchLabels:
app: api-gateway
- podSelector:
matchLabels:
app: order-service
ports:
- port: 8080
6. Валидация входных данных
Каждый сервис должен сам валидировать входные данные, не полагаясь на то, что вызывающий сервис уже провёл валидацию.
На собеседовании: покажите многослойную защиту: JWT на Gateway, mTLS между сервисами, Vault для секретов, Network Policies для сетевой изоляции. Частая ошибка — думать, что JWT-валидации на Gateway достаточно и внутренние сервисы не нужно защищать.