在Spring Gateway预过滤器中检查数据库的访问权限



我正在使用Spring Gateway,在那里我需要使用DB调用通过请求路径检查进一步的用户访问。我的存储库是这样的。

public Mono<ActionMapping> getByUri(String url)
....

这是我当前使用自定义UsernamePasswordAuthenticationToken实现的过滤器。

@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> exchange
.getPrincipal()
.filter(principal -> principal instanceof UserAuthenticationToken) // Custom implementation of UsernamePasswordAuthenticationToken
.cast(UserAuthenticationToken.class)
.map(userAuthenticationToken -> extractAuthoritiesAndSetThatToRequest(exchange, userAuthenticationToken))
.defaultIfEmpty(exchange)
.flatMap(chain::filter);
}
private ServerWebExchange extractAuthoritiesAndSetThatToRequest(ServerWebExchange exchange, UserAuthenticationToken authentication) {
var uriActionMapping = uriActionMappingRepository.findOneByUri(exchange.getRequest().getPath().toString()).block();
if ((uriActionMapping == null) || (authentication.getPermission().containsKey(uriActionMapping.getName()))) {
ServerHttpRequest request = exchange.getRequest()
.mutate()
.header("X-Auth", authentication.getName())
.build();
return exchange.mutate().request(request).build();
}
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.UNAUTHORIZED);
response.setComplete();
return exchange.mutate().response(response).build();
}

然而,这里有几个问题,首先是它阻塞了呼叫。此外,我不确定我是否需要对exchange进行突变才能返回这样的响应。在Spring Cloud Gateway中有没有使用过滤器来实现这一点。

是的,这是一个阻塞调用。

首先,Spring WebFlux是基于Reactor的。在反应堆中,大多数处理方法不会从Mono发射中接收到null,例如mapflatMap。当然,也有反例,比如doOnSuccess,另请参阅Mono的javadoc。

因此,我们可以使用处理方法来过滤结果,而不是block。当收到null值时,这些处理方法将返回一个空的Mono

其次,当授权失败时,我们应该返回一个空的Mono,而不是调用chain.filter。CCD_ 13表示";没事!只要在过滤器之后做点什么&";。另见RequestRateLimiterGatewayFilterFactory,它也突变了response

因此,我们应该将response设置为completed,如果授权失败,则返回一个空的Mono

试试这个:

@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> exchange
.getPrincipal()
.filter(principal -> principal instanceof UserAuthenticationToken) // Custom implementation of UsernamePasswordAuthenticationToken
.cast(UserAuthenticationToken.class)
.flatMap(userAuthenticationToken -> extractAuthoritiesAndSetThatToRequest(exchange, userAuthenticationToken))
.switchIfEmpty(Mono.defer(() -> exchange.getResponse().setComplete().then(Mono.empty())))
.flatMap(chain::filter);
}
// Maybe return empty Mono, e.g. findOneByUri not found, or Permissions does not containing
private Mono<ServerWebExchange> extractAuthoritiesAndSetThatToRequest(ServerWebExchange exchange, UserAuthenticationToken authentication) {
return uriActionMappingRepository.findOneByUri(exchange.getRequest().getPath().toString())
.filter(it -> authentication.getPermission().containsKey(it.getName()))
.map(it -> exchange.mutate()
.request(builder -> builder.header("X-Auth", authentication.getName()))
.build());
}

关于突变request,另请参见RewritePathGatewayFilterFactory

相关内容

  • 没有找到相关文章

最新更新