med*_*ech 6 webclient oauth spring-webclient
以下场景:
我有两个微服务 A 和 B。服务 A 是一个承载客户端,它有一个开放的 api 并接收来自必须由 keycloak 授权的客户端的请求。现在我想从服务 A 向服务 B 发送一个授权请求,它也是一个承载客户端。
我想过在 webclient builder 过程中将功能添加为过滤器功能,例如
@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());
}
Run Code Online (Sandbox Code Playgroud)
这是我在另一个问题中找到的一个例子。这对我来说似乎是正确的方法,但我可以在配置的那个阶段提供“字符串令牌”参数吗?我只是从 RestTemplate 切换到 Webclient,很抱歉,这是一个转储问题。
编辑:我可以在构建新的 Webclient 时手动设置标题。
return WebClient.builder().defaultHeader("Authorization", "Bearer "+ context.getTokenString()).build();
Run Code Online (Sandbox Code Playgroud)
正如我从 RestTemplate 知道的,它可以用作单例。还有一个 KeyCloakRestTemplate 会自动注入标头。
Webclient 是不可变的,所以当我注入它时,我不能只使用它并在之后添加标头。此外,我无法在启动时设置此标头,因为我必须等待获取承载标头并将其传入的请求。所以我想除了这样做之外没有其他方法吗?
或者直接在发送过程中设置:
webClient.get()
.uri(url)
.headers(h -> h.setBearerAuth(token))
.retrieve();
Run Code Online (Sandbox Code Playgroud)
我最终ExchangeFilterFunction
在类似的情况下使用了过滤器。就我而言,我有一个 Spring 组件,它检索要使用的令牌。如果context
您的示例中context.getTokenString()
是 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();
}
Run Code Online (Sandbox Code Playgroud)