fix(gateway): include stable request and trace ids in security errors
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package com.baiyue.gateway.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.core.io.buffer.DataBufferUtils;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class GatewaySecurityErrorResponseTest {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"UNAUTHORIZED, A0401",
|
||||
"FORBIDDEN, A0403"
|
||||
})
|
||||
void securityErrorsExposeStableCompleteCorrelationIds(String statusName, String code) throws Exception {
|
||||
var exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/api/platform/v1/orders").build());
|
||||
HttpStatus status = HttpStatus.valueOf(statusName);
|
||||
|
||||
GatewaySecurityConfig.writeError(exchange, objectMapper, status, code, "安全响应").block();
|
||||
|
||||
DataBuffer buffer = DataBufferUtils.join(exchange.getResponse().getBody()).block();
|
||||
assertThat(buffer).isNotNull();
|
||||
byte[] bytes = new byte[buffer.readableByteCount()];
|
||||
buffer.read(bytes);
|
||||
DataBufferUtils.release(buffer);
|
||||
String body = new String(bytes, StandardCharsets.UTF_8);
|
||||
JsonNode json = objectMapper.readTree(body);
|
||||
String requestId = json.get("requestId").asText();
|
||||
String traceId = json.get("traceId").asText();
|
||||
|
||||
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(status);
|
||||
assertThat(json.get("code").asText()).isEqualTo(code);
|
||||
assertThat(UUID.fromString(requestId)).isNotNull();
|
||||
assertThat(UUID.fromString(traceId)).isNotNull();
|
||||
assertThat(exchange.getResponse().getHeaders().getFirst("X-Request-Id")).isEqualTo(requestId);
|
||||
assertThat(exchange.getResponse().getHeaders().getFirst("X-Trace-Id")).isEqualTo(traceId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baiyue.gateway.filter;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class CorrelationIdWebFilterTest {
|
||||
@Test
|
||||
void replacesShortIncomingRequestIdAndCreatesTraceId() {
|
||||
var exchange = MockServerWebExchange.from(MockServerHttpRequest.get("/api/platform/v1/orders")
|
||||
.header(CorrelationIdWebFilter.HEADER, "a7612a59-6211")
|
||||
.build());
|
||||
|
||||
new CorrelationIdWebFilter().filter(exchange, ignored -> Mono.empty()).block();
|
||||
|
||||
String requestId = exchange.getResponse().getHeaders().getFirst(CorrelationIdWebFilter.HEADER);
|
||||
String traceId = exchange.getResponse().getHeaders().getFirst(CorrelationIdWebFilter.TRACE_HEADER);
|
||||
assertThat((String) requestId).matches("[0-9a-fA-F-]{36}");
|
||||
assertThat((String) traceId).matches("[0-9a-fA-F-]{36}");
|
||||
assertThat(requestId).isNotEqualTo("a7612a59-6211");
|
||||
assertThat((String) exchange.getAttribute(CorrelationIdWebFilter.REQUEST_ID_ATTRIBUTE)).isEqualTo(requestId);
|
||||
assertThat((String) exchange.getAttribute(CorrelationIdWebFilter.TRACE_ID_ATTRIBUTE)).isEqualTo(traceId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user