使用 spring-session 在微服务之间传播凭据的最佳方法

lej*_*e.n 6 spring-session spring-cloud

我们使用的架构与spring.io 上的这个伟大指南中描述的架构非常相似。我们的网关处理身份验证,会话使用 spring-session 存储在 Redis 中。我们微服务的端点是安全的,也使用 spring-session。

在微服务中,我需要调用另一个微服务的端点。我可以通过发现客户端轻松获取 URL,但我需要提供凭据,但我不确定实现该目标的最佳方法。

我正在考虑从 HttpRequest 获取 SESSION cookie,将其存储在某种线程局部变量或请求范围 bean 中,并在 RestTemplate 中使用它来调用第二个微服务。我需要这个请求范围的 bean,因为 RestTemplate 将用于服务层,即不在 MVC 控制器中,而且我不想用我从 cookie 获得的这个会话标识符污染我的服务层方法。

有没有更好的方法来满足这种需求?Spring Cloud 中是否已经对此提供了一些支持?

非常感谢您的意见

Rob*_*nch 5

此时访问 Spring Session id 的最简单方法是使用RequestContextHolder.getRequestAttributes().getId(). 一旦您有权访问它,您就可以编写自定义ClientHttpRequestInterceptor以在请求中包含会话 ID:

public SpringSessionClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
            throws IOException {
        boolean isMyService = ...;

        // very important not to send the session id to external services
        if(isMyService) {
            request.getHeaders().add("x-auth-token", RequestContextHolder.getRequestAttributes().getId());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,当您创建 RestTemplate 时,请确保添加SpringSessionClientHttpRequestInterceptor.

RestTemplate rest = new RestTemplate();
rest.getInterceptors().add(new SpringSessionClientHttpRequestInterceptor());
Run Code Online (Sandbox Code Playgroud)