优化
This commit is contained in:
+83
@@ -0,0 +1,83 @@
|
||||
package com.baiyue.gateway.filter;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class OverseasSecurityProjectionFilterTest {
|
||||
private final OverseasSecurityValidationClient client = mock(OverseasSecurityValidationClient.class);
|
||||
private final OverseasSecurityProjectionFilter filter = new OverseasSecurityProjectionFilter(client, new ObjectMapper());
|
||||
|
||||
@Test void disabledUserFailsWithA0401() {
|
||||
when(client.validate(42, 0, 3, 8)).thenReturn(Mono.just(
|
||||
new OverseasSecurityValidationClient.Result(false, "USER_DISABLED")));
|
||||
var exchange = exchange("/api/platform/v1/last-leg/orders");
|
||||
StepVerifier.create(filter.filter(exchange, ignored -> Mono.empty())).verifyComplete();
|
||||
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
assertThat(body(exchange)).contains("A0401");
|
||||
}
|
||||
|
||||
@Test void disabledTenantAndStalePermissionFailWithA0403() {
|
||||
for (String reason : new String[]{"TENANT_DISABLED", "PERMISSION_VERSION_STALE"}) {
|
||||
when(client.validate(42, 0, 3, 8)).thenReturn(Mono.just(
|
||||
new OverseasSecurityValidationClient.Result(false, reason)));
|
||||
var exchange = exchange("/api/merchant/v1/last-leg/orders");
|
||||
StepVerifier.create(filter.filter(exchange, ignored -> Mono.empty())).verifyComplete();
|
||||
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.FORBIDDEN);
|
||||
assertThat(body(exchange)).contains("A0403");
|
||||
}
|
||||
}
|
||||
|
||||
@Test void projectionUnavailableFailsClosed() {
|
||||
when(client.validate(42, 0, 3, 8)).thenReturn(Mono.error(new IllegalStateException("down")));
|
||||
var exchange = exchange("/api/platform/v1/last-leg/orders");
|
||||
StepVerifier.create(filter.filter(exchange, ignored -> Mono.empty())).verifyComplete();
|
||||
assertThat(exchange.getResponse().getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
|
||||
@Test void acceptedSecurityStateContinuesAndNonApiPathsDoNotCallProjection() {
|
||||
when(client.validate(42, 0, 3, 8)).thenReturn(Mono.just(
|
||||
new OverseasSecurityValidationClient.Result(true, null)));
|
||||
AtomicBoolean routed = new AtomicBoolean();
|
||||
StepVerifier.create(filter.filter(exchange("/api/platform/v1/last-leg/orders"), ignored -> {
|
||||
routed.set(true); return Mono.empty();
|
||||
})).verifyComplete();
|
||||
assertThat(routed).isTrue();
|
||||
|
||||
var isolatedClient = mock(OverseasSecurityValidationClient.class);
|
||||
var isolatedFilter = new OverseasSecurityProjectionFilter(isolatedClient, new ObjectMapper());
|
||||
StepVerifier.create(isolatedFilter.filter(exchange("/actuator/health"), ignored -> Mono.empty())).verifyComplete();
|
||||
verifyNoInteractions(isolatedClient);
|
||||
}
|
||||
|
||||
private static ServerWebExchange exchange(String path) {
|
||||
Jwt jwt = Jwt.withTokenValue("verified").header("alg", "RS256").subject("42")
|
||||
.issuedAt(Instant.now()).expiresAt(Instant.now().plusSeconds(300))
|
||||
.claim("tenant_id", 0L).claim("token_version", 3L).claim("permission_version", 8L).build();
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.get(path).build());
|
||||
return exchange.mutate().principal(Mono.just(new JwtAuthenticationToken(jwt,
|
||||
List.of(new SimpleGrantedAuthority("ROLE_PLATFORM_USER"))))).build();
|
||||
}
|
||||
|
||||
private static String body(ServerWebExchange exchange) {
|
||||
return ((org.springframework.mock.http.server.reactive.MockServerHttpResponse) exchange.getResponse())
|
||||
.getBodyAsString().block();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user