Initial commit: Complete Software Architecture course with 11 modules
- Added comprehensive course structure with 11 modules - Included theoretical content, practical examples, and tasks - Multi-language code examples (Java, Rust, Node.js, Python) - Detailed analysis of architectural approaches and trade-offs - Complete caching strategies documentation - Architecture examples from real-world systems (Twitter, Netflix, Uber) - Structured navigation and learning path - Ready for educational use
This commit is contained in:
commit
15e744da49
107 files changed
+61762
No files matched your search
@@ -0,0 +1,723 @@
|
||||
# Уязвимости и межсервисное взаимодействие
|
||||
|
||||
## Навигация
|
||||
- [🏠 Главная страница курса](../../../README.md)
|
||||
- [📚 Модуль 6](../README.md)
|
||||
|
||||
---
|
||||
|
||||
## Типы уязвимостей в микросервисной архитектуре
|
||||
|
||||
### 1. Уязвимости межсервисного взаимодействия
|
||||
|
||||
**Проблемы:**
|
||||
- Отсутствие аутентификации между сервисами
|
||||
- Передача чувствительных данных в открытом виде
|
||||
- Отсутствие валидации токенов
|
||||
- Man-in-the-middle атаки
|
||||
- Replay атаки
|
||||
|
||||
**Решения:**
|
||||
- Mutual TLS (mTLS)
|
||||
- Service-to-Service токены
|
||||
- API Gateway с аутентификацией
|
||||
- Token Validation Middleware (TVM)
|
||||
|
||||
### 2. TVM (Token Validation Middleware)
|
||||
|
||||
**TVM** — промежуточное ПО для валидации токенов между микросервисами.
|
||||
|
||||
**Принципы работы:**
|
||||
1. Сервис получает токен от клиента
|
||||
2. TVM валидирует токен
|
||||
3. TVM извлекает информацию о пользователе/сервисе
|
||||
4. TVM передает валидные данные в целевой сервис
|
||||
|
||||
**Технический пример - TVM Implementation:**
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class TokenValidationMiddleware {
|
||||
|
||||
@Autowired
|
||||
private JwtTokenService jwtTokenService;
|
||||
|
||||
@Autowired
|
||||
private ServiceRegistry serviceRegistry;
|
||||
|
||||
public ServiceTokenValidationResult validateServiceToken(String token, String targetService) {
|
||||
try {
|
||||
// Валидация токена
|
||||
Claims claims = jwtTokenService.validateToken(token);
|
||||
|
||||
// Проверка прав доступа к сервису
|
||||
if (!hasAccessToService(claims, targetService)) {
|
||||
return ServiceTokenValidationResult.denied("No access to service: " + targetService);
|
||||
}
|
||||
|
||||
// Проверка срока действия токена
|
||||
if (isTokenExpired(claims)) {
|
||||
return ServiceTokenValidationResult.denied("Token expired");
|
||||
}
|
||||
|
||||
// Извлечение информации о сервисе
|
||||
ServiceInfo serviceInfo = extractServiceInfo(claims);
|
||||
|
||||
return ServiceTokenValidationResult.success(serviceInfo);
|
||||
|
||||
} catch (JwtException e) {
|
||||
return ServiceTokenValidationResult.denied("Invalid token: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasAccessToService(Claims claims, String targetService) {
|
||||
List<String> allowedServices = claims.get("allowed_services", List.class);
|
||||
return allowedServices != null && allowedServices.contains(targetService);
|
||||
}
|
||||
|
||||
private boolean isTokenExpired(Claims claims) {
|
||||
Date expiration = claims.getExpiration();
|
||||
return expiration.before(new Date());
|
||||
}
|
||||
|
||||
private ServiceInfo extractServiceInfo(Claims claims) {
|
||||
return ServiceInfo.builder()
|
||||
.serviceId(claims.getSubject())
|
||||
.serviceName(claims.get("service_name", String.class))
|
||||
.permissions(claims.get("permissions", List.class))
|
||||
.issuedAt(claims.getIssuedAt())
|
||||
.expiresAt(claims.getExpiration())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// Service Token Validation Result
|
||||
@Data
|
||||
@Builder
|
||||
public class ServiceTokenValidationResult {
|
||||
private boolean valid;
|
||||
private String errorMessage;
|
||||
private ServiceInfo serviceInfo;
|
||||
|
||||
public static ServiceTokenValidationResult success(ServiceInfo serviceInfo) {
|
||||
return ServiceTokenValidationResult.builder()
|
||||
.valid(true)
|
||||
.serviceInfo(serviceInfo)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ServiceTokenValidationResult denied(String errorMessage) {
|
||||
return ServiceTokenValidationResult.builder()
|
||||
.valid(false)
|
||||
.errorMessage(errorMessage)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
// Service Info
|
||||
@Data
|
||||
@Builder
|
||||
public class ServiceInfo {
|
||||
private String serviceId;
|
||||
private String serviceName;
|
||||
private List<String> permissions;
|
||||
private Date issuedAt;
|
||||
private Date expiresAt;
|
||||
}
|
||||
```
|
||||
|
||||
**Rust примеры - TVM с Actix Web:**
|
||||
|
||||
```rust
|
||||
// Token Validation Middleware для Actix Web
|
||||
use actix_web::{web, HttpRequest, HttpResponse, Error, middleware::Next};
|
||||
use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct ServiceClaims {
|
||||
sub: String, // service_id
|
||||
service_name: String,
|
||||
allowed_services: Vec<String>,
|
||||
permissions: Vec<String>,
|
||||
iat: u64, // issued_at
|
||||
exp: u64, // expires_at
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ServiceInfo {
|
||||
pub service_id: String,
|
||||
pub service_name: String,
|
||||
pub permissions: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct TokenValidationMiddleware {
|
||||
decoding_key: DecodingKey,
|
||||
validation: Validation,
|
||||
}
|
||||
|
||||
impl TokenValidationMiddleware {
|
||||
pub fn new(secret: &str) -> Self {
|
||||
let mut validation = Validation::new(Algorithm::HS256);
|
||||
validation.set_issuer(&["microservices-platform"]);
|
||||
|
||||
Self {
|
||||
decoding_key: DecodingKey::from_secret(secret.as_ref()),
|
||||
validation,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validate_service_token(
|
||||
&self,
|
||||
token: &str,
|
||||
target_service: &str,
|
||||
) -> Result<ServiceInfo, String> {
|
||||
// Декодирование токена
|
||||
let token_data = decode::<ServiceClaims>(token, &self.decoding_key, &self.validation)
|
||||
.map_err(|e| format!("Token validation failed: {}", e))?;
|
||||
|
||||
let claims = token_data.claims;
|
||||
|
||||
// Проверка срока действия
|
||||
let now = chrono::Utc::now().timestamp() as u64;
|
||||
if claims.exp < now {
|
||||
return Err("Token expired".to_string());
|
||||
}
|
||||
|
||||
// Проверка прав доступа к сервису
|
||||
if !claims.allowed_services.contains(&target_service.to_string()) {
|
||||
return Err(format!("No access to service: {}", target_service));
|
||||
}
|
||||
|
||||
Ok(ServiceInfo {
|
||||
service_id: claims.sub,
|
||||
service_name: claims.service_name,
|
||||
permissions: claims.permissions,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware для Actix Web
|
||||
pub async fn token_validation_middleware(
|
||||
req: HttpRequest,
|
||||
next: Next,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
// Извлечение токена из заголовка
|
||||
let token = req.headers()
|
||||
.get("Authorization")
|
||||
.and_then(|h| h.to_str().ok())
|
||||
.and_then(|s| s.strip_prefix("Bearer "));
|
||||
|
||||
match token {
|
||||
Some(token) => {
|
||||
// Валидация токена
|
||||
let middleware = TokenValidationMiddleware::new("your-secret-key");
|
||||
let target_service = req.path().split('/').nth(1).unwrap_or("unknown");
|
||||
|
||||
match middleware.validate_service_token(token, target_service) {
|
||||
Ok(service_info) => {
|
||||
// Добавление информации о сервисе в контекст запроса
|
||||
req.extensions_mut().insert(service_info);
|
||||
next.run(req).await
|
||||
}
|
||||
Err(e) => Ok(HttpResponse::Unauthorized()
|
||||
.json(serde_json::json!({
|
||||
"error": "Token validation failed",
|
||||
"message": e
|
||||
})))
|
||||
}
|
||||
}
|
||||
None => Ok(HttpResponse::Unauthorized()
|
||||
.json(serde_json::json!({
|
||||
"error": "Missing authorization token"
|
||||
})))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Python примеры - TVM с FastAPI:**
|
||||
|
||||
```python
|
||||
# Token Validation Middleware для FastAPI
|
||||
from fastapi import FastAPI, HTTPException, Depends, Request
|
||||
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||
from jose import JWTError, jwt
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, List
|
||||
from pydantic import BaseModel
|
||||
|
||||
class ServiceClaims(BaseModel):
|
||||
sub: str
|
||||
service_name: str
|
||||
allowed_services: List[str]
|
||||
permissions: List[str]
|
||||
iat: int
|
||||
exp: int
|
||||
|
||||
class ServiceInfo(BaseModel):
|
||||
service_id: str
|
||||
service_name: str
|
||||
permissions: List[str]
|
||||
|
||||
class TokenValidationMiddleware:
|
||||
def __init__(self, secret_key: str):
|
||||
self.secret_key = secret_key
|
||||
self.algorithm = "HS256"
|
||||
|
||||
def validate_service_token(self, token: str, target_service: str) -> ServiceInfo:
|
||||
try:
|
||||
# Декодирование токена
|
||||
payload = jwt.decode(token, self.secret_key, algorithms=[self.algorithm])
|
||||
|
||||
# Проверка срока действия
|
||||
if datetime.utcnow().timestamp() > payload.get("exp", 0):
|
||||
raise HTTPException(status_code=401, detail="Token expired")
|
||||
|
||||
# Проверка прав доступа к сервису
|
||||
allowed_services = payload.get("allowed_services", [])
|
||||
if target_service not in allowed_services:
|
||||
raise HTTPException(
|
||||
status_code=403,
|
||||
detail=f"No access to service: {target_service}"
|
||||
)
|
||||
|
||||
return ServiceInfo(
|
||||
service_id=payload.get("sub"),
|
||||
service_name=payload.get("service_name"),
|
||||
permissions=payload.get("permissions", [])
|
||||
)
|
||||
|
||||
except JWTError as e:
|
||||
raise HTTPException(status_code=401, detail=f"Invalid token: {str(e)}")
|
||||
|
||||
# Dependency для FastAPI
|
||||
security = HTTPBearer()
|
||||
middleware = TokenValidationMiddleware("your-secret-key")
|
||||
|
||||
async def get_service_info(
|
||||
credentials: HTTPAuthorizationCredentials = Depends(security),
|
||||
request: Request = None
|
||||
) -> ServiceInfo:
|
||||
token = credentials.credentials
|
||||
target_service = request.url.path.split('/')[1] if request else "unknown"
|
||||
|
||||
return middleware.validate_service_token(token, target_service)
|
||||
|
||||
# Использование в FastAPI
|
||||
app = FastAPI()
|
||||
|
||||
@app.get("/api/orders")
|
||||
async def get_orders(service_info: ServiceInfo = Depends(get_service_info)):
|
||||
# Проверка прав доступа
|
||||
if "read:orders" not in service_info.permissions:
|
||||
raise HTTPException(status_code=403, detail="Insufficient permissions")
|
||||
|
||||
return {"message": "Orders retrieved", "service": service_info.service_name}
|
||||
```
|
||||
|
||||
**Node.js примеры - TVM с Express:**
|
||||
|
||||
```typescript
|
||||
// Token Validation Middleware для Express
|
||||
import express, { Request, Response, NextFunction } from 'express';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { Request as JWTRequest } from 'express-jwt';
|
||||
|
||||
interface ServiceClaims {
|
||||
sub: string;
|
||||
service_name: string;
|
||||
allowed_services: string[];
|
||||
permissions: string[];
|
||||
iat: number;
|
||||
exp: number;
|
||||
}
|
||||
|
||||
interface ServiceInfo {
|
||||
service_id: string;
|
||||
service_name: string;
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
class TokenValidationMiddleware {
|
||||
private secretKey: string;
|
||||
private algorithm: string = 'HS256';
|
||||
|
||||
constructor(secretKey: string) {
|
||||
this.secretKey = secretKey;
|
||||
}
|
||||
|
||||
validateServiceToken(token: string, targetService: string): ServiceInfo {
|
||||
try {
|
||||
// Декодирование токена
|
||||
const payload = jwt.verify(token, this.secretKey, {
|
||||
algorithms: [this.algorithm]
|
||||
}) as ServiceClaims;
|
||||
|
||||
// Проверка срока действия
|
||||
if (Date.now() / 1000 > payload.exp) {
|
||||
throw new Error('Token expired');
|
||||
}
|
||||
|
||||
// Проверка прав доступа к сервису
|
||||
if (!payload.allowed_services.includes(targetService)) {
|
||||
throw new Error(`No access to service: ${targetService}`);
|
||||
}
|
||||
|
||||
return {
|
||||
service_id: payload.sub,
|
||||
service_name: payload.service_name,
|
||||
permissions: payload.permissions
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
throw new Error(`Token validation failed: ${error.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Middleware для Express
|
||||
const middleware = new TokenValidationMiddleware('your-secret-key');
|
||||
|
||||
export const tokenValidationMiddleware = (req: Request, res: Response, next: NextFunction) => {
|
||||
try {
|
||||
const authHeader = req.headers.authorization;
|
||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||
return res.status(401).json({ error: 'Missing authorization token' });
|
||||
}
|
||||
|
||||
const token = authHeader.substring(7);
|
||||
const targetService = req.path.split('/')[2] || 'unknown';
|
||||
|
||||
const serviceInfo = middleware.validateServiceToken(token, targetService);
|
||||
|
||||
// Добавление информации о сервисе в контекст запроса
|
||||
(req as any).serviceInfo = serviceInfo;
|
||||
|
||||
next();
|
||||
} catch (error) {
|
||||
res.status(401).json({
|
||||
error: 'Token validation failed',
|
||||
message: error.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Использование в Express
|
||||
app.use('/api', tokenValidationMiddleware);
|
||||
|
||||
app.get('/api/orders', (req: Request, res: Response) => {
|
||||
const serviceInfo = (req as any).serviceInfo;
|
||||
|
||||
// Проверка прав доступа
|
||||
if (!serviceInfo.permissions.includes('read:orders')) {
|
||||
return res.status(403).json({ error: 'Insufficient permissions' });
|
||||
}
|
||||
|
||||
res.json({
|
||||
message: 'Orders retrieved',
|
||||
service: serviceInfo.service_name
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Mutual TLS (mTLS)
|
||||
|
||||
**mTLS** обеспечивает взаимную аутентификацию между сервисами.
|
||||
|
||||
**Java пример - Spring Boot с mTLS:**
|
||||
|
||||
```java
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class MTlsSecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
return http
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/public/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.x509(x509 -> x509
|
||||
.subjectPrincipalRegex("CN=(.*?)(?:,|$)")
|
||||
.userDetailsService(userDetailsService())
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UserDetailsService userDetailsService() {
|
||||
return username -> {
|
||||
// Валидация сертификата клиента
|
||||
if (isValidServiceCertificate(username)) {
|
||||
return User.builder()
|
||||
.username(username)
|
||||
.password("")
|
||||
.authorities("ROLE_SERVICE")
|
||||
.build();
|
||||
}
|
||||
throw new UsernameNotFoundException("Invalid service certificate");
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isValidServiceCertificate(String subject) {
|
||||
// Логика валидации сертификата
|
||||
return subject.startsWith("service-");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Service Mesh Security
|
||||
|
||||
**Istio Security Configuration:**
|
||||
|
||||
```yaml
|
||||
# PeerAuthentication для mTLS
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: PeerAuthentication
|
||||
metadata:
|
||||
name: default
|
||||
namespace: production
|
||||
spec:
|
||||
mtls:
|
||||
mode: STRICT
|
||||
|
||||
# AuthorizationPolicy для контроля доступа
|
||||
apiVersion: security.istio.io/v1beta1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
name: service-access
|
||||
namespace: production
|
||||
spec:
|
||||
rules:
|
||||
- from:
|
||||
- source:
|
||||
principals: ["cluster.local/ns/production/sa/order-service"]
|
||||
to:
|
||||
- operation:
|
||||
methods: ["GET", "POST"]
|
||||
paths: ["/api/orders/*"]
|
||||
```
|
||||
|
||||
### 5. API Gateway Security
|
||||
|
||||
**Kong Gateway Configuration:**
|
||||
|
||||
```yaml
|
||||
# Kong API Gateway с JWT аутентификацией
|
||||
apiVersion: configuration.konghq.com/v1
|
||||
kind: KongPlugin
|
||||
metadata:
|
||||
name: jwt-auth
|
||||
config:
|
||||
key_claim_name: iss
|
||||
secret_is_base64: false
|
||||
run_on_preflight: true
|
||||
---
|
||||
apiVersion: configuration.konghq.com/v1
|
||||
kind: KongIngress
|
||||
metadata:
|
||||
name: api-ingress
|
||||
upstream:
|
||||
healthchecks:
|
||||
active:
|
||||
healthy:
|
||||
interval: 30
|
||||
successes: 3
|
||||
unhealthy:
|
||||
interval: 10
|
||||
http_failures: 3
|
||||
```
|
||||
|
||||
### 6. Security Headers для микросервисов
|
||||
|
||||
**Java пример - Security Headers:**
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class SecurityHeadersFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
|
||||
// Security Headers
|
||||
httpResponse.setHeader("X-Content-Type-Options", "nosniff");
|
||||
httpResponse.setHeader("X-Frame-Options", "DENY");
|
||||
httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
|
||||
httpResponse.setHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
|
||||
httpResponse.setHeader("Content-Security-Policy", "default-src 'self'");
|
||||
httpResponse.setHeader("Referrer-Policy", "strict-origin-when-cross-origin");
|
||||
httpResponse.setHeader("Permissions-Policy", "geolocation=(), microphone=(), camera=()");
|
||||
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Rate Limiting для межсервисного взаимодействия
|
||||
|
||||
**Redis-based Rate Limiting:**
|
||||
|
||||
```java
|
||||
@Service
|
||||
public class InterServiceRateLimitingService {
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate<String, String> redisTemplate;
|
||||
|
||||
public boolean isAllowed(String serviceId, String targetService, int maxRequests, Duration window) {
|
||||
String key = String.format("rate_limit:%s:%s", serviceId, targetService);
|
||||
|
||||
// Sliding window rate limiting
|
||||
long now = System.currentTimeMillis();
|
||||
long windowStart = now - window.toMillis();
|
||||
|
||||
// Удаление старых записей
|
||||
redisTemplate.opsForZSet().removeRangeByScore(key, 0, windowStart);
|
||||
|
||||
// Подсчет текущих запросов
|
||||
Long currentCount = redisTemplate.opsForZSet().count(key, windowStart, now);
|
||||
|
||||
if (currentCount >= maxRequests) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Добавление нового запроса
|
||||
redisTemplate.opsForZSet().add(key, UUID.randomUUID().toString(), now);
|
||||
redisTemplate.expire(key, window);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 8. Audit Logging для межсервисного взаимодействия
|
||||
|
||||
**Structured Audit Logging:**
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class InterServiceAuditLogger {
|
||||
|
||||
private static final Logger auditLogger = LoggerFactory.getLogger("AUDIT");
|
||||
|
||||
public void logServiceCall(String sourceService, String targetService,
|
||||
String operation, boolean success, String details) {
|
||||
|
||||
Map<String, Object> auditData = Map.of(
|
||||
"timestamp", Instant.now().toString(),
|
||||
"source_service", sourceService,
|
||||
"target_service", targetService,
|
||||
"operation", operation,
|
||||
"success", success,
|
||||
"details", details,
|
||||
"correlation_id", MDC.get("correlationId")
|
||||
);
|
||||
|
||||
auditLogger.info("Inter-service call: {}", auditData);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9. Circuit Breaker для безопасности
|
||||
|
||||
**Resilience4j Circuit Breaker:**
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class SecureServiceClient {
|
||||
|
||||
private final CircuitBreaker circuitBreaker;
|
||||
private final Retry retry;
|
||||
|
||||
public SecureServiceClient() {
|
||||
this.circuitBreaker = CircuitBreaker.ofDefaults("secure-service");
|
||||
this.retry = Retry.ofDefaults("secure-service");
|
||||
}
|
||||
|
||||
@CircuitBreaker(name = "secure-service")
|
||||
@Retry(name = "secure-service")
|
||||
public ServiceResponse callSecureService(String serviceUrl, String token) {
|
||||
try {
|
||||
// Вызов защищенного сервиса
|
||||
return restTemplate.exchange(
|
||||
serviceUrl,
|
||||
HttpMethod.GET,
|
||||
createSecureRequest(token),
|
||||
ServiceResponse.class
|
||||
).getBody();
|
||||
} catch (Exception e) {
|
||||
// Логирование безопасности
|
||||
securityLogger.warn("Secure service call failed: {}", e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private HttpEntity<?> createSecureRequest(String token) {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(token);
|
||||
headers.set("X-Service-Name", "order-service");
|
||||
headers.set("X-Request-ID", UUID.randomUUID().toString());
|
||||
|
||||
return new HttpEntity<>(headers);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 10. Security Monitoring и Alerting
|
||||
|
||||
**Security Metrics:**
|
||||
|
||||
```java
|
||||
@Component
|
||||
public class SecurityMetrics {
|
||||
|
||||
private final MeterRegistry meterRegistry;
|
||||
private final Counter authenticationFailures;
|
||||
private final Counter authorizationFailures;
|
||||
private final Timer serviceCallDuration;
|
||||
|
||||
public SecurityMetrics(MeterRegistry meterRegistry) {
|
||||
this.meterRegistry = meterRegistry;
|
||||
this.authenticationFailures = Counter.builder("security.auth.failures")
|
||||
.description("Authentication failures")
|
||||
.register(meterRegistry);
|
||||
this.authorizationFailures = Counter.builder("security.authz.failures")
|
||||
.description("Authorization failures")
|
||||
.register(meterRegistry);
|
||||
this.serviceCallDuration = Timer.builder("security.service.call.duration")
|
||||
.description("Secure service call duration")
|
||||
.register(meterRegistry);
|
||||
}
|
||||
|
||||
public void recordAuthenticationFailure(String reason) {
|
||||
authenticationFailures.increment(Tags.of("reason", reason));
|
||||
}
|
||||
|
||||
public void recordAuthorizationFailure(String resource) {
|
||||
authorizationFailures.increment(Tags.of("resource", resource));
|
||||
}
|
||||
|
||||
public Timer.Sample startServiceCallTimer() {
|
||||
return Timer.start(meterRegistry);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
Безопасность межсервисного взаимодействия требует комплексного подхода:
|
||||
|
||||
1. **Аутентификация** - проверка подлинности сервисов
|
||||
2. **Авторизация** - контроль доступа к ресурсам
|
||||
3. **Шифрование** - защита данных в транзите
|
||||
4. **Мониторинг** - отслеживание подозрительной активности
|
||||
5. **Аудит** - логирование всех операций
|
||||
6. **Rate Limiting** - защита от злоупотреблений
|
||||
7. **Circuit Breaker** - устойчивость к сбоям
|
||||
|
||||
TVM и mTLS являются ключевыми технологиями для обеспечения безопасности в микросервисной архитектуре.
|
||||
Reference in new issue
Block a user