'Why does Spring Cloud Gateway not process request further after changing body?
I have to write a filter, that will replace token on user login. Here is the code:
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
log.info("AuthenticationFilterOne: path - {}, if predicate - {}",
path,
!loggingFilterProperties.getIgnoredUris().contains(path)
&& noAuthProperties.checkNoAuthEndpoint(path)
);
if (!loggingFilterProperties.getIgnoredUris().contains(path)
&& noAuthProperties.checkNoAuthEndpoint(path)) {
log.info("AuthenticationFilterOne: in if block, path - {}, predicate - {}, ignoredUris - {}, NoAuthEndpoints - {}",
path,
!loggingFilterProperties.getIgnoredUris().contains(path)
&& noAuthProperties.checkNoAuthEndpoint(path),
Arrays.toString(loggingFilterProperties.getIgnoredUris().toArray()),
Arrays.toString(noAuthProperties.getNoAuthEndpoints().toArray())
);
GatewayContext gatewayContext = new GatewayContext();
gatewayContext.setPath(path);
exchange.getAttributes().put(GatewayContext.CACHE_GATEWAY_CONTEXT, gatewayContext);
HttpHeaders headers = request.getHeaders();
MediaType contentType = headers.getContentType();
if (contentType != null && "application/x-thrift".equals(contentType.toString())) {
return readBody(exchange, chain, gatewayContext);
}
}
return chain.filter(exchange);
}
@SuppressWarnings({"AnonInnerLength", "MultipleStringLiterals", "LineLength", "CommentsIndentation"})
private Mono<Void> readBody(
ServerWebExchange exchange,
GatewayFilterChain chain,
GatewayContext gatewayContext) {
/**
* join the body
*/
return DataBufferUtils.join(exchange.getRequest().getBody())
.flatMap(dataBuffer -> {
byte[] bytes = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(bytes);
DataBufferUtils.release(dataBuffer);
TProtocol protocol = protocolFactory.getProtocol(new TMemoryInputTransport(bytes));
int startPosition = findStartPosition(protocol);
UserData userData = null;
try {
userData = authenticationGateway.verify();
userData = authenticationGateway.verify(extractAuthToken(protocol, new AuthenticationTokenAuthEntity()));
} catch (TException e) {
log.error("In AuthenticationFilterOne: error get user data");
}
AuthenticationTokenAuthEntity authenticationTokenAuthEntity = extractAuthToken(protocol, new AuthenticationTokenAuthEntity());
int endPosition = findEndPosition(protocol);
byte[] processed = ArrayUtils.addAll(
ArrayUtils.addAll(
getSkippedPart(protocol, startPosition),
serializeUserData(protocolFactory, userData)
),
getAfterTokenPart(protocol, endPosition, bytes.length)
);
log.info("AuthenticationFilterOne: userData - {}", userData);
Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
DataBuffer buffer =
exchange.getResponse().bufferFactory().wrap(processed);
DataBufferUtils.retain(buffer);
return Mono.just(buffer);
});
/**
* repackage ServerHttpRequest
*/
ServerHttpRequest mutatedRequest =
new ServerHttpRequestDecorator(exchange.getRequest()) {
@Override
public Flux<DataBuffer> getBody() {
return cachedFlux;
}
};
/**
* mutate exchage with new ServerHttpRequest
*/
ServerWebExchange mutatedExchange =
exchange.mutate().request(mutatedRequest).build();
HttpHeaders headers = mutatedExchange.getRequest().getHeaders();
StringBuilder builder = new StringBuilder("{");
for (Map.Entry<String, List<String>> e: headers.entrySet()) {
builder.append("[key - ").append(e.getKey()).append(": value - ")
.append(Arrays.toString(e.getValue().toArray())).append("]");
}
builder.append("}");
/**
* read body string with default messageReaders
*/
return ServerRequest.create(mutatedExchange, MESSAGE_READERS)
.bodyToMono(String.class)
.doOnNext(objectValue -> {
log.info("PostBody:{}, headers - {}", objectValue, builder.toString());
gatewayContext.setCacheBody(objectValue);
/* log.debug("[GatewayContext]Read JsonBody:{}",
objectValue);*/
}).then(chain.filter(mutatedExchange));
});
}
It replaces the token, but it doesn't process the request further to an application and I cannot understand why. I have tried RewriteFunction<String, String> but, it doesn't work, because there is issue when I tried convert string to array of bytes and then to thrift structure.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
