I am using Spring Gateway, where I need to check further user access by Request path using DB call. My repository is like this.
public Mono<ActionMapping> getByUri(String url)
....
This is my current filter where I am using custom UsernamePasswordAuthenticationToken
implementation.
@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();
}
However, there are several problems here, first that it is blocking call. Also I am not sure I need to mutate exchange
to return response like that. Is there anyway achieve this using filter in Spring Cloud Gateway.