Spring Cloud Gateway -验证GatewayFilterChain中的流程



我是Spring反应器编程的新手,目前我遇到了一个需求,需要在Spring GatewayFilterChain中验证授权头

,我已经创建了一个"AuthenticationFilter"代码片段:

public class AuthenticationFilter implements GlobalFilter {
@Autowired
private WebClient.Builder webClientBuilder;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//Do API call to auth the "Authorization" Header data from the request
AuthHeaderDto authHeaderDto = retrieveHeaderDto(exchange.getRequest());
Mono<AuthResponse> monoAuthResponse = webClientBuilder.build().post()
.uri(uri)
.body(BodyInserters.fromPublisher(Mono.just(authHeaderDto), AuthHeaderDto.class))
.retrieve()
.bodyToMono(AuthResponse.class);
//TODO: base on monoAuthResponse(parameter "isValid":true/false) 
//      to set different status code (401 for false, 200 for true) to ServerWebExchange
//      and continue the filter chain, i.e., return chain.filter(exchange);
}
}

我的问题是,链的继续进程实际上需要等待验证请求(即阻塞),在这种情况下,我可以通过什么方式实现?

谢谢你的帮助。

您可以这样做。但它没有经过测试。

@Component
public class GlobalGatewayPreFilter extends AbstractGatewayFilterFactory<GlobalGatewayPreFilter.Config> {
private final WebClient client;
@Autowired
public GlobalGatewayPreFilter() {
super(Config.class);
this.client = WebClient.create("http://blahblah");
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) ->
exchange.getPrincipal()
.filterWhen(authenticationToken -> checkAuth(exchange))
.map(authenticationToken -> exchange)
.switchIfEmpty(Mono.defer(() -> setErrorResponse(exchange.getResponse()).setComplete().then(Mono.empty())))
.flatMap(chain::filter);
}
private ServerHttpResponse setErrorResponse(ServerHttpResponse serverHttpResponse) {
serverHttpResponse.setStatusCode(HttpStatus.UNAUTHORIZED);
return serverHttpResponse;
}
private Mono<Boolean> checkAuth(ServerWebExchange exchange) {
if (!exchange.getRequest().getHeaders().containsKey("Authorization")) {
return Mono.empty();
}
// Map your response and send true false
return Mono.just(true);
}
public static class Config {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
}

但是我不建议在这里做这种验证签入。我宁愿使用Spring Security来做这个,但这取决于你。

相关内容

  • 没有找到相关文章