This commit is contained in:
2026-08-25 16:40:48 +08:00
parent 1f6f1a0677
commit 87c5e18ca6
93 changed files with 1154 additions and 527 deletions
@@ -7,7 +7,7 @@ import java.time.Duration;
@ConfigurationProperties(prefix = "baiyue.security.overseas-projection")
public record OverseasSecurityProjectionProperties(String serviceUrl, String internalServiceToken, Duration timeout) {
public OverseasSecurityProjectionProperties {
if (serviceUrl == null || serviceUrl.isBlank()) throw new IllegalArgumentException("必须配置 OVERSEAS_SECURITY_SERVICE_URL");
if (serviceUrl == null || serviceUrl.isBlank()) throw new IllegalArgumentException("必须配置 LASTLEG_SECURITY_SERVICE_URL");
if (internalServiceToken == null || internalServiceToken.getBytes(java.nio.charset.StandardCharsets.UTF_8).length < 32) {
throw new IllegalArgumentException("INTERNAL_SERVICE_TOKEN 至少需要 32 字节");
}
@@ -9,7 +9,7 @@ import reactor.core.publisher.Mono;
@Component
public class HttpOverseasSecurityValidationClient implements OverseasSecurityValidationClient {
private static final String PATH = "/internal/overseas-security/v1/validate";
private static final String PATH = "/internal/lastleg/security/v1/validate";
private final WebClient client;
private final OverseasSecurityProjectionProperties properties;
@@ -19,10 +19,10 @@ public class HttpOverseasSecurityValidationClient implements OverseasSecurityVal
}
@Override
public Mono<Result> validate(long userId, long tenantId, long tokenVersion, long permissionVersion) {
public Mono<Result> validate(long userId, long tenantId, long permissionVersion) {
return client.post().uri(properties.serviceUrl() + PATH).contentType(MediaType.APPLICATION_JSON)
.header("X-Internal-Service-Token", properties.internalServiceToken())
.bodyValue(new Request(userId, tenantId, tokenVersion, permissionVersion))
.bodyValue(new Request(userId, tenantId, permissionVersion))
.retrieve().bodyToMono(JsonNode.class).timeout(properties.timeout()).flatMap(body -> {
JsonNode data = body == null ? null : body.path("data");
if (data == null || data.isMissingNode() || !data.has("valid")) {
@@ -33,5 +33,5 @@ public class HttpOverseasSecurityValidationClient implements OverseasSecurityVal
});
}
private record Request(long userId, long tenantId, long tokenVersion, long permissionVersion) { }
private record Request(long userId, long tenantId, long permissionVersion) { }
}
@@ -38,12 +38,11 @@ public class OverseasSecurityProjectionFilter implements GlobalFilter, Ordered {
JwtAuthenticationToken authentication) {
Long userId = number(authentication.getToken().getSubject());
Long tenantId = number(authentication.getToken().getClaim("tenant_id"));
Long tokenVersion = number(authentication.getToken().getClaim("token_version"));
Long permissionVersion = number(authentication.getToken().getClaim("permission_version"));
if (userId == null || tenantId == null || tokenVersion == null || permissionVersion == null) {
if (userId == null || tenantId == null || permissionVersion == null) {
return Mono.error(new SecurityProjectionFailure("A0401", "海外令牌安全版本声明缺失"));
}
return client.validate(userId, tenantId, tokenVersion, permissionVersion)
return client.validate(userId, tenantId, permissionVersion)
.switchIfEmpty(Mono.error(new SecurityProjectionFailure("A0401", "海外安全状态校验不可用")))
.flatMap(result -> {
if (result.valid()) return chain.filter(exchange);
@@ -3,6 +3,6 @@ package com.baiyue.gateway.filter;
import reactor.core.publisher.Mono;
public interface OverseasSecurityValidationClient {
Mono<Result> validate(long userId, long tenantId, long tokenVersion, long permissionVersion);
Mono<Result> validate(long userId, long tenantId, long permissionVersion);
record Result(boolean valid, String failureReason) { }
}