java使用Spring Cloud Gateway过滤器重试带有修改头的REST调用?
我目前正在开发一个REST“代理”。其想法是在命令行上启动一个jar,为其提供“代理”REST API的基本url和用于身份验证的现有密钥。代理处理身份验证/续订,并将所有REST调用转发到目标API
我认为Spring Cloud Gateway可能非常适合这种情况,并且使用请求链接成功地实现了认证方面的工作:
@Configuration
public class FilterConfiguration {
@Bean
public RouteLocator mock(RouteLocatorBuilder builder, @Value("${gateway.url}") String url, @Value("${secret.key}") String secretKey, MyGatewayFilterFactory filterFactory) {
return builder.routes()
.route("pass-through", predicateSpec -> predicateSpec
.path("/authentication/sign/in/**", "/authentication/renew/**")
.uri(url))
.route("requires-auth", predicateSpec -> predicateSpec
.alwaysTrue()
.filters(gatewayFilterSpec -> gatewayFilterSpec
.filter(filterFactory.apply(new MyGatewayFilterFactory.Config(secretKey)))
)
.uri(url))
.build();
}
}
@Component
@RequiredArgsConstructor
public class MyGatewayFilterFactory extends AbstractGatewayFilterFactory<MyGatewayFilterFactory .Config> {
private final WebClient webClient;
@Override
public GatewayFilter apply(MyGatewayFilterFactory.Config config) {
return (exchange, chain) -> Optional.of(AccessTokensHolder.tokens)
.map(AtomicReference::get)
.map(Mono::just)
.orElseGet(() -> this.signIn(config.getSecretKey()))
.flatMap(accessTokens -> {
exchange.getRequest()
.mutate()
.header(HttpHeaders.AUTHORIZATION, String.format("%s %s", accessTokens.getType(), accessTokens.getAccessToken()));
return chain.filter(exchange);
})
.onErrorResume(t -> Mono.empty())
.then(Mono.fromRunnable(this.postRequest(exchange)));
}
private Mono<AccessTokens> signIn(String secretKey) {
// uses the webClient to get the access tokens for the secretKey ...
}
private Runnable postRequest(ServerWebExchange exchange) {
return () -> {
ServerHttpResponse response = exchange.getResponse();
if (HttpStatus.PRECONDITION_FAILED.equals(response.getStatusCode())) {
// todo : HELP!
}
};
}
@Data
@RequiredArgsConstructor
public static class Config {
public final String secretKey;
}
private static final class AccessTokensHolder {
private static final AtomicReference<AccessTokens> tokens = new AtomicReference<>();
}
}
我的问题是如何处理回复。如果经过身份验证的调用以412响应,我需要能够进行webClient调用以刷新访问令牌,然后再次执行原始调用(使用修改的授权头)。我不知道如何实现这一点(对于SCG和WebFlux来说,这是一个相当新的概念)
(顺便说一句,如果有人知道实现这一点的更好/更简单的方法,我洗耳恭听!)
任何帮助都将不胜感激
干杯
共 (0) 个答案