Spring Cloud Security 安全控制实战指南

一、OAuth2.0集成

核心概念

OAuth2.0是当前微服务架构中最流行的授权框架,Spring Cloud Security提供了完整的OAuth2.0实现方案。

图1

授权服务器配置

@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
            .withClient("clientapp")
            .secret(passwordEncoder().encode("123456"))
            .authorizedGrantTypes("password", "refresh_token")
            .scopes("read", "write")
            .accessTokenValiditySeconds(3600);
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

实践建议

  1. 生产环境务必使用JDBC存储客户端信息而非内存存储
  2. 合理设置token有效期,通常access_token 2小时,refresh_token 7天
  3. 建议采用PKCE扩展增强公共客户端安全性

二、JWT支持

JWT优势

  • 自包含:减少身份验证服务器查询
  • 无状态:适合分布式系统
  • 可验证:数字签名保证完整性

配置JWT令牌

@Configuration
public class JwtConfig {
    
    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }
    
    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey("my-secret-key"); // 生产环境使用非对称加密
        return converter;
    }
}

JWT最佳实践

  1. 敏感信息不要放入JWT
  2. 使用非对称加密(RS256)而非对称加密(HS256)
  3. 设置合理的过期时间
  4. 实现token黑名单机制用于注销

三、资源服务器配置

基础配置

@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
    
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/api/public/**").permitAll()
            .antMatchers("/api/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated();
    }
}

方法级安全控制

@RestController
@RequestMapping("/api")
public class UserController {
    
    @PreAuthorize("hasRole('ADMIN')")
    @GetMapping("/users")
    public List<User> listUsers() {
        // ...
    }
    
    @PostAuthorize("returnObject.username == principal.username")
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        // ...
    }
}

安全建议

  1. 遵循最小权限原则
  2. 敏感操作增加二次验证
  3. 定期审计权限分配

四、API安全防护

1. 签名验证

public class ApiSignInterceptor implements HandlerInterceptor {
    
    @Override
    public boolean preHandle(HttpServletRequest request, 
                           HttpServletResponse response, 
                           Object handler) {
        String sign = request.getHeader("X-API-SIGN");
        String timestamp = request.getHeader("X-API-TIMESTAMP");
        
        // 验证时间戳有效性
        if(!validateTimestamp(timestamp)) {
            throw new ApiException("无效请求");
        }
        
        // 验证签名
        String expectedSign = generateSign(request, timestamp);
        if(!expectedSign.equals(sign)) {
            throw new ApiException("签名错误");
        }
        
        return true;
    }
}

2. 防重放攻击

public class ReplayAttackFilter extends OncePerRequestFilter {
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Override
    protected void doFilterInternal(HttpServletRequest request,
                                  HttpServletResponse response,
                                  FilterChain filterChain) {
        String nonce = request.getHeader("X-API-NONCE");
        if(StringUtils.isEmpty(nonce)) {
            throw new ApiException("缺少防重放参数");
        }
        
        // 检查nonce是否已使用
        Boolean result = redisTemplate.opsForValue()
            .setIfAbsent("nonce:"+nonce, "1", 5, TimeUnit.MINUTES);
        if(Boolean.FALSE.equals(result)) {
            throw new ApiException("请求已过期或重复");
        }
        
        filterChain.doFilter(request, response);
    }
}

3. 限流防护

@Configuration
public class RateLimitConfig {
    
    @Bean
    public FilterRegistrationBean<RateLimitFilter> rateLimitFilter() {
        FilterRegistrationBean<RateLimitFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new RateLimitFilter());
        registration.addUrlPatterns("/api/*");
        registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return registration;
    }
}

public class RateLimitFilter implements Filter {
    
    private RateLimiter rateLimiter = RateLimiter.create(100); // 每秒100个请求
    
    @Override
    public void doFilter(ServletRequest request, 
                       ServletResponse response,
                       FilterChain chain) {
        if(!rateLimiter.tryAcquire()) {
            ((HttpServletResponse)response).sendError(429, "请求过于频繁");
            return;
        }
        chain.doFilter(request, response);
    }
}

API安全最佳实践

  1. 全站HTTPS加密
  2. 敏感参数加密传输
  3. 关键操作日志记录
  4. 定期安全扫描和渗透测试

五、安全监控与审计

安全事件日志

@Aspect
@Component
public class SecurityAuditAspect {
    
    @Autowired
    private AuditLogService auditLogService;
    
    @AfterReturning(
        pointcut = "@annotation(org.springframework.security.access.prepost.PreAuthorize)",
        returning = "result")
    public void auditSuccess(JoinPoint jp, Object result) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        auditLogService.log(auth.getName(), 
                          jp.getSignature().getName(),
                          "SUCCESS");
    }
    
    @AfterThrowing(
        pointcut = "@annotation(org.springframework.security.access.prepost.PreAuthorize)",
        throwing = "ex")
    public void auditFailure(JoinPoint jp, Exception ex) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        auditLogService.log(auth != null ? auth.getName() : "ANONYMOUS",
                          jp.getSignature().getName(),
                          "FAILURE: " + ex.getMessage());
    }
}

总结

Spring Cloud Security为微服务架构提供了全面的安全解决方案:

  1. OAuth2.0 + JWT实现安全的身份认证和授权
  2. 资源服务器细粒度权限控制
  3. 多层次的API安全防护体系
  4. 完善的安全监控和审计机制

在实际项目中,建议根据业务需求组合使用这些安全组件,并定期进行安全评估和升级,以应对不断变化的安全威胁。

添加新评论