From 7fcef906dee898518298d5af87e1a6103b828c48 Mon Sep 17 00:00:00 2001 From: figmar Date: Mon, 31 Aug 2026 04:15:58 +0800 Subject: [PATCH] fix(gateway): Spring 6.2 + Base64 API migrations (ResponseCookie, statusCode, encodeToString, orElseThrow, effectively-final) - CasdoorOauthController: stateCookie -> ResponseCookie (HttpCookie.builder removed in 6.2), B64URL encoder/decoder split, encodeBytes -> encodeToString - CasdoorClient: resp.status() -> resp.statusCode() - CasdoorIdTokenVerifier: Optional.orElseThrow in map (type witness), no ternary+Mono.error - CasdoorUserService: throw instead of Mono.error inside fromCallable (type inference) - AuthFilter: effectively-final local for lambda capture --- .../deepdata/gateway/common/filter/AuthFilter.java | 3 ++- .../infrastructure/casdoor/CasdoorClient.java | 2 +- .../casdoor/CasdoorIdTokenVerifier.java | 9 ++++----- .../infrastructure/casdoor/CasdoorUserService.java | 7 +++---- .../interfaces/rest/CasdoorOauthController.java | 12 +++++++----- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/backend/api-gateway/src/main/java/com/deepdata/gateway/common/filter/AuthFilter.java b/backend/api-gateway/src/main/java/com/deepdata/gateway/common/filter/AuthFilter.java index 32517e5..528c2ef 100644 --- a/backend/api-gateway/src/main/java/com/deepdata/gateway/common/filter/AuthFilter.java +++ b/backend/api-gateway/src/main/java/com/deepdata/gateway/common/filter/AuthFilter.java @@ -90,10 +90,11 @@ public class AuthFilter implements GlobalFilter, Ordered { ssoUser = request.getHeaders().getFirst("X-User-Name"); } if (StringUtils.isNotBlank(ssoUser)) { + final String ssoUserFinal = ssoUser; log.info("SSO mode detected, adding User header: {}", ssoUser); ServerHttpRequest mutatedRequest = request.mutate() .headers(httpHeaders -> { - httpHeaders.set(USER_HEADER, ssoUser); + httpHeaders.set(USER_HEADER, ssoUserFinal); }) .build(); ServerWebExchange mutatedExchange = exchange.mutate() diff --git a/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorClient.java b/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorClient.java index 75c1074..76fcbae 100644 --- a/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorClient.java +++ b/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorClient.java @@ -122,7 +122,7 @@ public class CasdoorClient { } private Mono errorBody(ClientResponse resp) { - return resp.bodyToMono(String.class).defaultIfEmpty(resp.status().toString()); + return resp.bodyToMono(String.class).defaultIfEmpty(resp.statusCode().toString()); } private static String enc(String s) { diff --git a/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorIdTokenVerifier.java b/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorIdTokenVerifier.java index c4c790b..68191db 100644 --- a/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorIdTokenVerifier.java +++ b/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorIdTokenVerifier.java @@ -119,11 +119,10 @@ public class CasdoorIdTokenVerifier { "id_token kid not found in JWKS after refresh")); } return loadKeys(true) - .flatMap(k2 -> Optional.ofNullable(parseWithKid(idToken, k2))) - .flatMap(o2 -> o2.isPresent() - ? Mono.just(o2.get()) - : Mono.error(new CasdoorIdTokenException( - "id_token kid not found in JWKS after refresh"))); + .map(k2 -> Optional.ofNullable(parseWithKid(idToken, k2))) + .map(o2 -> o2.orElseThrow(() -> + new CasdoorIdTokenException( + "id_token kid not found in JWKS after refresh"))); }); } diff --git a/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorUserService.java b/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorUserService.java index 3ccf3ed..d66abf0 100644 --- a/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorUserService.java +++ b/backend/api-gateway/src/main/java/com/deepdata/gateway/infrastructure/casdoor/CasdoorUserService.java @@ -62,8 +62,7 @@ public class CasdoorUserService { User user = findByUsername(username); if (user != null) { if (!user.isEnabled()) { - return Mono.error(new CasdoorProvisionException( - "local user disabled: " + username)); + throw new CasdoorProvisionException("local user disabled: " + username); } user.setLastLoginAt(now); if (hasText(claims.email()) && !claims.email().equals(user.getEmail())) { @@ -74,8 +73,8 @@ public class CasdoorUserService { return new ProvisionedUser(user, userService.generateToken(user), false); } if (!props.isAutoProvision()) { - return Mono.error(new CasdoorProvisionException( - "local user not found and auto-provision disabled: " + username)); + throw new CasdoorProvisionException( + "local user not found and auto-provision disabled: " + username); } User created = createUser(claims, username, now); try { diff --git a/backend/api-gateway/src/main/java/com/deepdata/gateway/interfaces/rest/CasdoorOauthController.java b/backend/api-gateway/src/main/java/com/deepdata/gateway/interfaces/rest/CasdoorOauthController.java index 30f180c..eeca7b8 100644 --- a/backend/api-gateway/src/main/java/com/deepdata/gateway/interfaces/rest/CasdoorOauthController.java +++ b/backend/api-gateway/src/main/java/com/deepdata/gateway/interfaces/rest/CasdoorOauthController.java @@ -11,6 +11,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.http.HttpCookie; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseCookie; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -64,6 +65,7 @@ public class CasdoorOauthController { private static final SecureRandom RANDOM = new SecureRandom(); private static final Base64.Encoder B64URL = Base64.getUrlEncoder().withoutPadding(); + private static final Base64.Decoder B64URL_DEC = Base64.getUrlDecoder(); private final CasdoorProperties props; private final CasdoorClient casdoorClient; @@ -75,8 +77,8 @@ public class CasdoorOauthController { public Mono> login(@RequestParam(name = "next", required = false) String next, ServerWebExchange exchange) { String safeNext = sanitizeNext(next); - String state = B64URL.encodeBytes(randomBytes(32)); - String cookieValue = state + "." + B64URL.encodeBytes(safeNext.getBytes(StandardCharsets.UTF_8)); + String state = B64URL.encodeToString(randomBytes(32)); + String cookieValue = state + "." + B64URL.encodeToString(safeNext.getBytes(StandardCharsets.UTF_8)); exchange.getResponse().addCookie( stateCookie(cookieValue, Duration.ofSeconds(props.getStateTtlSeconds()))); @@ -184,7 +186,7 @@ public class CasdoorOauthController { private static String decodeNext(String encoded) { try { - return new String(B64URL.decode(encoded), StandardCharsets.UTF_8); + return new String(B64URL_DEC.decode(encoded), StandardCharsets.UTF_8); } catch (IllegalArgumentException e) { return "/"; } @@ -201,8 +203,8 @@ public class CasdoorOauthController { return cookie == null ? null : cookie.getValue(); } - private HttpCookie stateCookie(String value, Duration maxAge) { - HttpCookie.Builder builder = HttpCookie.builder(props.getStateCookieName()); + private ResponseCookie stateCookie(String value, Duration maxAge) { + ResponseCookie.ResponseCookieBuilder builder = ResponseCookie.from(props.getStateCookieName()); if (value != null) { builder.value(value); }