API安全架构:认证、防护与限流
API安全架构:认证、防护与限流
API认证架构
API认证是安全防护的第一道防线,支持多种认证方式以适应不同场景。
// 多种认证方式支持
@Component
public class APIAuthenticator {
private final Map<String, AuthMethod> authMethods;
private final RateLimiter rateLimiter;
public AuthenticationResult authenticate(HttpServletRequest request) {
// 1. 检查速率限制
String clientId = extractClientId(request);
if (!rateLimiter.tryAcquire(clientId)) {
return AuthenticationResult.blocked("请求过于频繁");
}
// 2. 选择认证方式
String authHeader = request.getHeader("Authorization");
AuthMethod method = selectAuthMethod(authHeader);
// 3. 执行认证
return method.authenticate(request);
}
private AuthMethod selectAuthMethod(String authHeader) {
if (authHeader == null) {
return authMethods.get("anonymous");
} else if (authHeader.startsWith("Bearer ")) {
return authMethods.get("jwt");
} else if (authHeader.startsWith("Basic ")) {
return authMethods.get("basic");
} else if (authHeader.startsWith("ApiKey ")) {
return authMethods.get("api_key");
}
return authMethods.get("default");
}
}
// JWT认证方法
@Component
public class JWTAuthMethod implements AuthMethod {
private final JWTValidator validator;
@Override
public AuthenticationResult authenticate(HttpServletRequest request) {
String token = request.getHeader("Authorization")
.substring("Bearer ".length());
try {
Claims claims = validator.validateToken(token);
User user = userService.findById(claims.getSubject());
return AuthenticationResult.success(user, claims);
} catch (JWTException e) {
return AuthenticationResult.failed("令牌验证失败: " + e.getMessage());
}
}
}
输入验证与防注入
// 输入验证器
@Component
public class InputValidator {
private final Validator validator;
private final Sanitizer sanitizer;
public ValidationResult validate(Object input, Class<?> validationGroup) {
Set<ConstraintViolation<Object>> violations = validator.validate(input, validationGroup);
if (!violations.isEmpty()) {
return ValidationResult.failure(violations);
}
// 自定义安全验证
if (!validateSecurityConstraints(input)) {
return ValidationResult.failure("安全约束验证失败");
}
return ValidationResult.success();
}
private boolean validateSecurityConstraints(Object input) {
String json = objectMapper.writeValueAsString(input);
// SQL注入检测
if (containsSQLInjection(json)) {
return false;
}
// XSS检测
if (containsXSS(json)) {
return false;
}
// 命令注入检测
if (containsCommandInjection(json)) {
return false;
}
return true;
}
private boolean containsSQLInjection(String input) {
String[] patterns = {
"(?i)(union\\s+select)",
"(?i)(or\\s+\\d+\\s*=\\s*\\d+)",
"(?i)(;\\s*drop\\s+table)",
"(?i)(--\\s*$)"
};
return Arrays.stream(patterns)
.anyMatch(pattern -> input.matches(pattern));
}
}
速率限制实现
// 多层速率限制
@Component
public class MultiLayerRateLimiter {
private final RedisTemplate<String, String> redis;
private final RateLimitConfig config;
// 令牌桶算法
public boolean tryAcquireTokenBucket(String key, RateLimitRule rule) {
String redisKey = "ratelimit:token:" + key;
LuaScript script = new DefaultRedisScript<>(TOKEN_BUCKET_SCRIPT, Boolean.class);
Long result = redis.execute(script,
List.of(redisKey),
rule.getCapacity(),
rule.getRefillRate(),
rule.getTokens(),
System.currentTimeMillis());
return result == 1;
}
// 滑动窗口算法
public boolean tryAcquireSlidingWindow(String key, RateLimitRule rule) {
String redisKey = "ratelimit:sliding:" + key;
long now = System.currentTimeMillis();
long windowStart = now - rule.getWindowSize();
// 移除窗口外的请求
redis.opsForZSet().removeRangeByScore(redisKey, 0, windowStart);
// 获取当前窗口内的请求数
Long currentCount = redis.opsForZSet().zCard(redisKey);
if (currentCount >= rule.getMaxRequests()) {
return false;
}
// 记录当前请求
redis.opsForZSet().add(redisKey, String.valueOf(now), now);
redis.expire(redisKey, rule.getWindowSize() / 1000 + 1);
return true;
}
// 分布式限流(基于用户)
public RateLimitResult checkUserLimit(String userId, RateLimitRule rule) {
String key = "user:" + userId;
if (!tryAcquireTokenBucket(key, rule)) {
return RateLimitResult.limited(rule.getRetryAfter());
}
return RateLimitResult.allowed();
}
// 分布式限流(基于IP)
public RateLimitResult checkIPLimit(String ip, RateLimitRule rule) {
String key = "ip:" + ip;
if (!tryAcquireSlidingWindow(key, rule)) {
return RateLimitResult.limited(rule.getRetryAfter());
}
return RateLimitResult.allowed();
}
}
安全监控与告警
// API安全监控
@Service
public class APISecurityMonitor {
private final SecurityEventPublisher eventPublisher;
private final AlertService alertService;
public void monitorRequest(SecurityContext context) {
// 检测异常模式
List<SecurityThreat> threats = detectThreats(context);
for (SecurityThreat threat : threats) {
// 发布安全事件
eventPublisher.publish(SecurityEvent.builder()
.type(threat.getType())
.severity(threat.getSeverity())
.source(context.getClientIp())
.details(threat.getDetails())
.build());
// 触发告警
if (threat.getSeverity() == Severity.HIGH) {
alertService.sendAlert(Alert.builder()
.type("API_SECURITY_THREAT")
.title(threat.getType())
.message(threat.getDescription())
.build());
}
}
}
private List<SecurityThreat> detectThreats(SecurityContext context) {
List<SecurityThreat> threats = new ArrayList<>();
// 检测暴力破解
if (isBruteForceAttempt(context)) {
threats.add(SecurityThreat.bruteForce(context.getClientIp()));
}
// 检测异常访问模式
if (isAnomalousAccess(context)) {
threats.add(SecurityThreat.anomalousAccess(context));
}
// 检测数据泄露尝试
if (isDataExfiltrationAttempt(context)) {
threats.add(SecurityThreat.dataExfiltration(context));
}
return threats;
}
}
API安全架构通过多层次的认证、验证、限流和监控,构建了全面的API保护体系。