暂存提交

This commit is contained in:
2026-07-30 18:01:36 +08:00
commit 2f4e159356
368 changed files with 20370 additions and 0 deletions
@@ -0,0 +1,55 @@
package com.baiyue.gateway.config;
import org.junit.jupiter.api.Test;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import java.time.Instant;
class AppScopeAuthorizationManagerTest {
@Test
void acceptsMatchingApplicationScope() {
var manager = new AppScopeAuthorizationManager("MERCHANT");
StepVerifier.create(manager.check(Mono.just(authentication("MERCHANT")), null))
.expectNextMatches(decision -> decision.isGranted())
.verifyComplete();
}
@Test
void rejectsDifferentApplicationScope() {
var manager = new AppScopeAuthorizationManager("PLATFORM");
StepVerifier.create(manager.check(Mono.just(authentication("MERCHANT")), null))
.expectNextMatches(decision -> !decision.isGranted())
.verifyComplete();
}
@Test
void rejectsMissingApplicationScope() {
var manager = new AppScopeAuthorizationManager("PLATFORM");
Jwt jwt = Jwt.withTokenValue("token")
.header("alg", "none")
.subject("1")
.issuedAt(Instant.now())
.expiresAt(Instant.now().plusSeconds(60))
.build();
StepVerifier.create(manager.check(Mono.just(new JwtAuthenticationToken(
jwt, java.util.List.of(new SimpleGrantedAuthority("authenticated")))), null))
.expectNextMatches(decision -> !decision.isGranted())
.verifyComplete();
}
private JwtAuthenticationToken authentication(String appCode) {
Jwt jwt = Jwt.withTokenValue("token")
.header("alg", "none")
.subject("1")
.issuedAt(Instant.now())
.expiresAt(Instant.now().plusSeconds(60))
.claim("app_code", appCode)
.build();
return new JwtAuthenticationToken(jwt,
java.util.List.of(new SimpleGrantedAuthority("authenticated")));
}
}
@@ -0,0 +1,65 @@
package com.baiyue.gateway.config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.test.web.reactive.server.WebTestClient;
@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"
})
@AutoConfigureWebTestClient
class GatewayCorsConfigurationTest {
private static final String PROFILE_URL =
"http://localhost/api/merchant/v1/iam/tenant/profile";
@Autowired
private WebTestClient webTestClient;
@Test
void allowedOriginCanCompletePutPreflightWithoutToken() {
webTestClient.options()
.uri(PROFILE_URL)
.header(HttpHeaders.ORIGIN, "http://localhost:5173")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.PUT.name())
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS, "authorization,content-type")
.exchange()
.expectStatus().isOk()
.expectHeader().valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "http://localhost:5173")
.expectHeader().value(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,
value -> org.assertj.core.api.Assertions.assertThat(value).contains("PUT"))
.expectHeader().value(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
value -> org.assertj.core.api.Assertions.assertThat(value.toLowerCase())
.contains("authorization", "content-type"))
.expectHeader().doesNotExist(HttpHeaders.WWW_AUTHENTICATE);
}
@Test
void rejectedOriginDoesNotReceiveCorsPermission() {
webTestClient.options()
.uri(PROFILE_URL)
.header(HttpHeaders.ORIGIN, "https://untrusted.example.com")
.header(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD, HttpMethod.PUT.name())
.exchange()
.expectStatus().isForbidden()
.expectHeader().doesNotExist(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN);
}
@Test
void corsDoesNotMakeProtectedActualRequestAnonymous() {
webTestClient.get()
.uri(PROFILE_URL)
.header(HttpHeaders.ORIGIN, "http://localhost:5173")
.exchange()
.expectStatus().isUnauthorized()
.expectHeader().valueEquals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "http://localhost:5173");
}
}