← 返回首页
🔒

API安全架构:认证、防护与限流

📂 architecture ⏱ 3 min 503 words

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保护体系。