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); } }
官方资源
- Spring Cloud OpenFeign 官方文档:https://spring.io/projects/spring-cloud-openfeign
- Spring Security OAuth2:https://spring.io/guides/tutorials/spring-boot-oauth2/
本节小结
在本节中,我们学习了:
第一个是 Feign 安全配置。 如何配置 Feign 客户端的安全。
第二个是令牌传递。 如何在服务间传递令牌。
第三个是服务间认证。 如何实现服务间认证。
第四个是安全最佳实践。 服务间安全通信的最佳实践。
这就是服务间安全通信。正确配置服务间安全可以保证微服务系统的安全性。
在下一节,我们将学习资源服务器配置。