From 8834bd70234d2bb0fcc539a55a3b9e29e1088b5a Mon Sep 17 00:00:00 2001 From: HopeLi <1278288511@qq.com> Date: Tue, 29 Jul 2025 20:22:55 +0800 Subject: [PATCH] =?UTF-8?q?0729=20ljc=20=20=E5=8D=87=E7=BA=A7=E4=B8=BAOIDC?= =?UTF-8?q?=E7=89=88=E6=9C=AC=EF=BC=8C=E8=8B=A5=E5=87=BA=E7=8E=B0=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E5=8F=AF=E9=80=89=E6=8B=A9=E5=9B=9E=E9=80=80=E7=89=88?= =?UTF-8?q?=E6=9C=AC=EF=BC=8Cversion=201.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/oauth2/OAuth2OpenController.java | 64 +++++++++++++++++-- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/modules/module-system-biz/src/main/java/cd/casic/module/system/controller/admin/oauth2/OAuth2OpenController.java b/modules/module-system-biz/src/main/java/cd/casic/module/system/controller/admin/oauth2/OAuth2OpenController.java index 5eab326d..bb257d3c 100644 --- a/modules/module-system-biz/src/main/java/cd/casic/module/system/controller/admin/oauth2/OAuth2OpenController.java +++ b/modules/module-system-biz/src/main/java/cd/casic/module/system/controller/admin/oauth2/OAuth2OpenController.java @@ -34,10 +34,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.time.ZoneId; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import static cd.casic.framework.commons.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception0; @@ -249,7 +246,7 @@ public class OAuth2OpenController { @RequestParam(value = "nonce", required = false) String nonce) { @SuppressWarnings("unchecked") - Map scopes = JsonUtils.parseObject(scope, Map.class); + Map scopes = parseOAuth2Scopes(scope); scopes = ObjectUtil.defaultIfNull(scopes, Collections.emptyMap()); // 0. 校验用户已经登录。通过 Spring Security 实现 @@ -290,14 +287,40 @@ public class OAuth2OpenController { return success(getImplicitGrantRedirect(getLoginUserId(), client, approveScopes, redirectUri, state)); } + /** + * 根据 response_type 获取对应的授权类型 + * + * @param responseType 响应类型 + * @return OAuth2GrantTypeEnum 授权类型 + */ private static OAuth2GrantTypeEnum getGrantTypeEnum(String responseType) { + // OAuth2 标准响应类型 if (StrUtil.equals(responseType, "code")) { return OAuth2GrantTypeEnum.AUTHORIZATION_CODE; } - if (StrUtil.equalsAny(responseType, "token")) { + + // OAuth2 + OIDC 扩展响应类型(都属于 Implicit 类型处理) + if (StrUtil.equalsAny(responseType, "token", "id_token", "id_token token", "code id_token")) { return OAuth2GrantTypeEnum.IMPLICIT; } - throw exception0(BAD_REQUEST.getCode(), "response_type 参数值只允许 code 和 token"); + + throw exception0(BAD_REQUEST.getCode(), StrUtil.format("不支持的 response_type 参数值: {}", responseType)); + } + + /** + * 检查是否为有效的 OIDC 响应类型 + * + * @param responseType 响应类型 + * @return boolean 是否为有效的 OIDC 响应类型 + */ + private static boolean isValidOIDCResponseType(String responseType) { + return StrUtil.equalsAny(responseType, + "code", // OAuth2 Authorization Code + "token", // OAuth2 Implicit + "id_token", // OIDC Implicit + "id_token token", // OIDC Implicit + "code id_token" // OIDC Hybrid + ); } private String getImplicitGrantRedirect(Long userId, OAuth2ClientDO client, @@ -413,4 +436,31 @@ public class OAuth2OpenController { private String createIDTokenWithNonce(Long userId, String clientId, List scopes, String nonce) { return oauth2GrantService.grantIDToken(userId, getUserType(), clientId, scopes, nonce); } + + + private Map parseOAuth2Scopes(String scopeString) { + if (StrUtil.isBlank(scopeString)) { + return Collections.emptyMap(); + } + + try { + // 首先尝试作为 JSON 解析(为了向后兼容旧的实现) + return JsonUtils.parseObject(scopeString, Map.class); + } catch (Exception jsonException) { + // 如果 JSON 解析失败,按照 OAuth2 标准处理(空格分隔的字符串) + try { + Map scopes = new HashMap<>(); + String[] scopeArray = scopeString.split("\\s+"); // 使用正则表达式按空白字符分割 + for (String scope : scopeArray) { + if (StrUtil.isNotBlank(scope)) { + scopes.put(scope, true); + } + } + return scopes; + } catch (Exception e) { + log.warn("解析 scope 字符串时发生错误: {}", scopeString, e); + return Collections.emptyMap(); + } + } + } }