Spring Cloud Gateway - Anforderungskörper im Filter verbraucht, Antwort nicht an den Client zurückgegeben (leere Antwort
Posted: 19 May 2025, 11:56
Ich erstelle einen Feder-Cloud-Gateway-Filter, der das Anforderungsbehörde liest, um eine Nutzlastsignatur zu validieren, bevor die Anfrage an nachgeschaltete Dienste weitergeleitet wird (wie ein Kontodienst für Anmeldung). Ich kann die Antwort aus dem nachgeschalteten Dienst in den Protokollen sehen. /> Ich mutiere den Serverwebexchange mit der neuen Anforderung und der Anrufkette. Filter (...). Blockieren Sie Call (.blockoptional () auf dem DB-Aufruf), alles funktioniert von End-to-End-der nachgeschaltete Dienst wird aufgerufen, und der Kunde erhält die erwartete Antwort. Antwort? < /p>
Warum funktioniert der erste bei der Arbeit und der zweite nicht
Code: Select all
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
boolean excludeFromAuth = validateRouteExclusions(exchange);
List payloadSignature = exchange.getRequest().getHeaders().get("X-Sign");
List timeStamp = exchange.getRequest().getHeaders().get("T-S");
List userAgent = exchange.getRequest().getHeaders().get("X-U-A");
List contentType = exchange.getRequest().getHeaders().get(HttpHeaders.CONTENT_TYPE);
if (excludeFromAuth) {
return chain.filter(exchange);
}
if (userAgent == null || userAgent.isEmpty()) {
return onError(exchange, HttpStatus.FORBIDDEN);
}
if (timeStamp == null || timeStamp.isEmpty()) {
return onError(exchange, HttpStatus.FORBIDDEN);
}
if (payloadSignature == null || payloadSignature.isEmpty()) {
return onError(exchange, HttpStatus.FORBIDDEN);
}
String requestHash = payloadSignature.get(0);
paddedTimeStamp = "";
if (!isTimeStampValid(timeStampHeader)) {// validate time stamp
return onError(exchange, HttpStatus.FORBIDDEN);
}
Optional signatureRecord = repository
.findByAgentKey(userAgent.get(0)).blockOptional();
if (signatureRecord.isPresent()) {
// Assign or use the signatureRecord here
signature = signatureRecord.get();
boolean hasApplicationJsonHeader = hasApplicationJsonHeader(contentType);
if (!hasApplicationJsonHeader) {
return isValidUrl(requestHash, exchange.getRequest().getURI().toString())
? chain.filter(exchange)
: onError(exchange, HttpStatus.FORBIDDEN);
}
return validateSignaturesV3(requestHash, exchange, chain);
}
return onError(exchange, HttpStatus.FORBIDDEN);
}
< /code>
Oben ist der Blockierungsanruf, der schlecht Ja ist, da er den reaktiven Vorgang besiegt, aber wenn ich von Postman testet, ruft das Gateway den Account -Service -Protokoll der Benutzer zurück und gibt die Anmeldeantwort < /p>
Die folgende vollständige Login -Reaktion, die die Login -Reaktion zurückgibt, aber die Login -Reaktion zurückgibt. @Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
boolean excludeFromAuth = validateRouteExclusions(exchange);
List payloadSignature = exchange.getRequest().getHeaders().get("X-Payload-Signature");
List timeStamp = exchange.getRequest().getHeaders().get("T-SP");
List userAgent = exchange.getRequest().getHeaders().get("X-U-A");
List contentType = exchange.getRequest().getHeaders().get(HttpHeaders.CONTENT_TYPE);
if (excludeFromAuth) {
return chain.filter(exchange);
}
if (userAgent == null || userAgent.isEmpty()) {
return onError(exchange, HttpStatus.FORBIDDEN);
}
if (timeStamp == null || timeStamp.isEmpty()) {
return onError(exchange, HttpStatus.FORBIDDEN);
}
if (payloadSignature == null || payloadSignature.isEmpty()) {
return onError(exchange, HttpStatus.FORBIDDEN);
}
String requestHash = payloadSignature.get(0);
paddedTimeStamp = "";
if (!isTimeStampValid(timeStampHeader)) {// validate time stamp
return onError(exchange, HttpStatus.FORBIDDEN);
}
return repository.findByAgentKey(userAgent.get(0))
.flatMap(signatureRecord -> {
// Assign or use the signatureRecord here
signature = signatureRecord;
boolean hasApplicationJsonHeader = hasApplicationJsonHeader(contentType);
if (hasApplicationJsonHeader) {
return validateSignaturesV3(requestHash, exchange, chain);
} else {
if (isValidUrl(requestHash, exchange.getRequest().getURI().toString())) {
return chain.filter(exchange); // Continue chain if valid
}
return onError(exchange, HttpStatus.FORBIDDEN);
}
}).switchIfEmpty(onError(exchange, HttpStatus.FORBIDDEN));
}