Spring WebClient在头部设置Bearer授权令牌

16
以下情景:
我有两个微服务A和B。服务A是一个Bearer客户端,具有开放式API,并接收必须由keycloak授权的客户端请求。现在我想从服务A发送一个经过授权的请求到也是Bearer客户端的服务B。
我考虑在webclient构建过程中添加过滤器功能,例如:
@Bean
WebClient webClient() {
    return WebClient.builder()
            .filter(authHeader())
            .build();
}

private ExchangeFilterFunction authHeader(String token) {
    return (request, next) -> next.exchange(ClientRequest.from(request).headers((headers) -> {
        headers.setBearerAuth(token);
    }).build());
}

这是我在另一个问题中找到的示例。对我来说似乎是正确的方式,但我可以在配置的那个阶段提供“String token”参数吗?
我刚刚从RestTemplate转换到WebClient,所以如果这是一个傻瓜问题,我很抱歉。
编辑: 我能够在构建新的WebClient时手动设置标题。
return WebClient.builder()
        .defaultHeader("Authorization", "Bearer "+ context.getTokenString())
        .build();

据我所知,从RestTemplate可以使用Singleton模式。还有一个KeyCloakRestTemplate,它会自动注入标头。 WebClient是不可变的,因此当我注入它时,不能仅仅使用它,然后在之后添加标头。此外,我不能在启动时设置此标头,因为我必须等待请求以获取bearer标头并将其传递。所以我猜没有其他办法比这种方式更好了?

如果我将Bearer令牌设置为“默认标头”,它对我无效。我必须在请求时将其作为标头插入。有任何想法为什么? - Flimtix
2个回答

7

或者在发送过程中设置:

webClient.get()
    .uri(url)
    .headers(h -> h.setBearerAuth(token))
    .retrieve();

3

我最终在类似的情况下使用了ExchangeFilterFunction过滤器。在我的情况下,我有一个Spring组件来检索要使用的令牌。如果你的context.getTokenString()示例中的context是一个Spring bean,那么你应该能够做到同样的事情:

@Bean
WebClient webClient(SomeContext context) {
    return WebClient.builder()
            .filter((request, next) -> next.exchange(
                    withBearerAuth(request, context.getTokenValue())))
            .build();
}

private static ClientRequest withBearerAuth(ClientRequest request, 
                                            String token) {
    return ClientRequest.from(request)
            .header(HttpHeaders.AUTHORIZATION, "Bearer " + token)
            .build();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接