14.6服务间安全通信

分类: Spring Cloud Security

服务间安全通信

服务间安全通信是微服务安全的重要组成部分。本节将学习服务间安全通信。

本节将学习:Feign 安全配置、令牌传递、服务间认证,以及安全最佳实践。

Feign 安全配置

请求拦截器

@Configuration public class FeignSecurityConfig { @Bean public RequestInterceptor requestInterceptor() { return requestTemplate -> { // 从 SecurityContext 获取令牌 Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.getCredentials() instanceof String) { String token = (String) authentication.getCredentials(); requestTemplate.header("Authorization", "Bearer " + token); } }; } }

令牌传递

@Component public class TokenRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String token = request.getHeader("Authorization"); if (token != null) { requestTemplate.header("Authorization", token); } } }

令牌传递

自动传递

@Configuration public class FeignConfig { @Bean public RequestInterceptor oauth2FeignRequestInterceptor() { return new OAuth2FeignRequestInterceptor(); } } public class OAuth2FeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { OAuth2AuthenticationToken authentication = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); if (authentication != null) { OAuth2AccessToken accessToken = authentication.getAccessToken(); requestTemplate.header("Authorization", "Bearer " + accessToken.getTokenValue()); } } }

手动传递

@Service public class OrderService { @Autowired private UserServiceClient userServiceClient; @Autowired private TokenService tokenService; public Order createOrder(OrderDTO orderDTO) { String token = tokenService.getCurrentToken(); // 手动设置令牌 return userServiceClient.getUser(orderDTO.getUserId(), token); } }

服务间认证

服务凭证

@Configuration public class ServiceAuthConfig { @Bean public ClientCredentialsResourceDetails clientCredentialsResourceDetails() { ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails(); details.setClientId("service-client"); details.setClientSecret("service-secret"); details.setAccessTokenUri("http://auth-server/oauth/token"); details.setGrantType("client_credentials"); return details; } }

OAuth2 客户端

@Configuration public class OAuth2FeignClientConfig { @Bean public OAuth2FeignRequestInterceptor oAuth2FeignRequestInterceptor( OAuth2ClientContext oAuth2ClientContext, ClientCredentialsResourceDetails resource) { return new OAuth2FeignRequestInterceptor(oAuth2ClientContext, resource); } }

安全最佳实践

令牌管理

令牌管理最佳实践:

  • 使用短期访问令牌
  • 安全存储刷新令牌
  • 及时撤销过期令牌
  • 监控令牌使用情况

服务间通信

服务间通信最佳实践:

  • 使用 HTTPS
  • 验证服务身份
  • 限制服务权限
  • 记录通信日志

错误处理

@Component public class FeignErrorDecoder implements ErrorDecoder { @Override public Exception decode(String methodKey, Response response) { if (response.status() == 401) { return new UnauthorizedException("Unauthorized"); } if (response.status() == 403) { return new ForbiddenException("Forbidden"); } return new RuntimeException("Service call failed"); } }

重试机制

@Configuration public class FeignRetryConfig { @Bean public Retryer retryer() { return new Retryer.Default(1000, 2000, 3); } }

官方资源

本节小结

在本节中,我们学习了:

第一个是 Feign 安全配置。 如何配置 Feign 客户端的安全。

第二个是令牌传递。 如何在服务间传递令牌。

第三个是服务间认证。 如何实现服务间认证。

第四个是安全最佳实践。 服务间安全通信的最佳实践。

这就是服务间安全通信。正确配置服务间安全可以保证微服务系统的安全性。

在下一节,我们将学习资源服务器配置。