暂存提交

This commit is contained in:
2026-07-31 18:10:32 +08:00
parent e834482717
commit 9a37657148
35 changed files with 435 additions and 44 deletions
+1
View File
@@ -15,6 +15,7 @@
| JWT 与安全配置项 | `config/GatewaySecurityProperties.java` |
| Redis 会话过滤 | `config/RedisTokenSessionWebFilter.java` |
| CORS | `config/GatewayCorsConfiguration.java`、`GatewayCorsProperties.java` |
| 请求标识 | `filter/CorrelationIdWebFilter.java`;包括预检和安全失败响应的 `X-Request-Id` |
| 可信身份头清理/注入 | `filter/TrustedIdentityHeaderFilter.java` |
| 本地路由 | `src/main/resources/application.yml` |
| 国内环境与 Swagger 聚合 | `src/main/resources/application-cn.yml`、`../config/nacos/{local,cn}/gateway.yml` |
@@ -205,3 +205,14 @@ springdoc:
url: /integration-service/v3/api-docs
- name: event-bridge
url: /event-bridge-service/v3/api-docs
logging:
file:
name: "${LOGGING_FILE_NAME:${LOG_PATH:./logs}/${spring.application.name}.log}"
logback:
rollingpolicy:
file-name-pattern: "${LOGGING_ROLLING_FILE_NAME_PATTERN:${LOG_PATH:./logs}/${spring.application.name}.%d{yyyy-MM-dd}.%i.log.gz}"
max-file-size: "${LOGGING_ROLLING_MAX_FILE_SIZE:100MB}"
max-history: "${LOGGING_ROLLING_MAX_HISTORY:30}"
total-size-cap: "${LOGGING_ROLLING_TOTAL_SIZE_CAP:5GB}"
clean-history-on-start: "${LOGGING_ROLLING_CLEAN_HISTORY_ON_START:false}"
@@ -9,13 +9,17 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.test.web.reactive.server.WebTestClient;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertThrows;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = {
"spring.cloud.nacos.discovery.enabled=false",
"spring.cloud.nacos.discovery.register-enabled=false",
"spring.cloud.nacos.config.enabled=false",
"spring.cloud.gateway.discovery.locator.enabled=false",
"baiyue.security.jwt-secret=test-jwt-secret-at-least-32-bytes-long",
"baiyue.cors.allowed-origins=http://localhost:5173"
"baiyue.cors.allowed-origins=http://localhost:5173,http://localhost:5174"
})
@AutoConfigureWebTestClient
@DisplayName("网关跨域配置功能")
@@ -26,6 +30,30 @@ class GatewayCorsConfigurationTest {
@Autowired
private WebTestClient webTestClient;
@Test
void wildcardOriginIsRejected() {
assertThrows(IllegalArgumentException.class, () -> new GatewayCorsProperties(
List.of("*"), List.of("GET"), List.of("Content-Type"), List.of(), false, 3600));
}
@Test
void localhost5174CanPreflightLoginWithoutTokenAndKeepsRequestId() {
webTestClient.options()
.uri("http://localhost/api/auth/login")
.header(HttpHeaders.ORIGIN, "http://localhost:5174")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.POST.name())
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "content-type")
.exchange()
.expectStatus().isOk()
.expectHeader().valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "http://localhost:5174")
.expectHeader().value(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
value -> org.assertj.core.api.Assertions.assertThat(value).contains("POST"))
.expectHeader().value(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
value -> org.assertj.core.api.Assertions.assertThat(value.toLowerCase()).contains("content-type"))
.expectHeader().exists("X-Request-Id")
.expectHeader().doesNotExist(HttpHeaders.WWW_AUTHENTICATE);
}
@Test
void allowedOriginCanCompletePutPreflightWithoutToken() {
webTestClient.options()
@@ -52,6 +80,7 @@ class GatewayCorsConfigurationTest {
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.PUT.name())
.exchange()
.expectStatus().isForbidden()
.expectHeader().exists("X-Request-Id")
.expectHeader().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN);
}