0729 ljc 升级为OIDC版本,若出现问题可选择回退版本,version 1.0

This commit is contained in:
HopeLi 2025-07-29 20:22:55 +08:00
parent 5f56977ded
commit 8834bd7023

View File

@ -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<String, Boolean> scopes = JsonUtils.parseObject(scope, Map.class);
Map<String, Boolean> 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<String> scopes, String nonce) {
return oauth2GrantService.grantIDToken(userId, getUserType(), clientId, scopes, nonce);
}
private Map<String, Boolean> 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<String, Boolean> 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();
}
}
}
}