xlsea
2024-01-08 845b57e9311945b323c760ad66af59621e290573
JustAuth 整合 TopIam 单点登录
已添加2个文件
已修改4个文件
172 ■■■■■ 文件已修改
ruoyi-admin/src/main/resources/application-dev.yml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopiamSource.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
script/sql/ry_vue_5.X.sql 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/src/main/resources/application-dev.yml
@@ -189,6 +189,13 @@
      client-id: 876892492581044224
      client-secret: x1Y5MTMwNzIwMjMxNTM4NDc3Mzche8
      redirect-uri: ${justauth.address}/social-callback?source=maxkey
    topiam:
      # topiam æœåŠ¡å™¨åœ°å€
      server-url: http://127.0.0.1:1989/api/v1/authorize/y0q************spq***********8ol
      client-id: 449c4*********937************759
      client-secret: ac7***********1e0************28d
      redirect-uri: ${justauth.address}/social-callback?source=topiam
      scopes: [openid, email, phone, profile]
    qq:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/config/properties/SocialLoginConfigProperties.java
@@ -2,6 +2,8 @@
import lombok.Data;
import java.util.List;
/**
 * ç¤¾äº¤ç™»å½•配置
 *
@@ -65,4 +67,9 @@
     */
    private String serverUrl;
    /**
     * è¯·æ±‚范围
     */
    private List<String> scopes;
}
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopIamRequest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
package org.dromara.common.social.topiam;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.xkcoding.http.support.HttpHeader;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.exception.AuthException;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthToken;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthDefaultRequest;
import me.zhyd.oauth.utils.HttpUtils;
import me.zhyd.oauth.utils.UrlBuilder;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.json.utils.JsonUtils;
import static org.dromara.common.social.topiam.AuthTopiamSource.TOPIAM;
/**
 * TopIAM è®¤è¯è¯·æ±‚
 *
 * @author xlsea
 * @since 2024-01-06
 */
@Slf4j
public class AuthTopIamRequest extends AuthDefaultRequest {
    public static final String SERVER_URL = SpringUtils.getProperty("justauth.type.topiam.server-url");
    /**
     * è®¾å®šå½’属域
     */
    public AuthTopIamRequest(AuthConfig config) {
        super(config, TOPIAM);
    }
    public AuthTopIamRequest(AuthConfig config, AuthStateCache authStateCache) {
        super(config, TOPIAM, authStateCache);
    }
    @Override
    protected AuthToken getAccessToken(AuthCallback authCallback) {
        String body = doPostAuthorizationCode(authCallback.getCode());
        Dict object = JsonUtils.parseMap(body);
        checkResponse(object);
        return AuthToken.builder()
            .accessToken(object.getStr("access_token"))
            .refreshToken(object.getStr("refresh_token"))
            .idToken(object.getStr("id_token"))
            .tokenType(object.getStr("token_type"))
            .scope(object.getStr("scope"))
            .build();
    }
    @Override
    protected AuthUser getUserInfo(AuthToken authToken) {
        String body = doGetUserInfo(authToken);
        Dict object = JsonUtils.parseMap(body);
        checkResponse(object);
        return AuthUser.builder()
            .uuid(object.getStr("sub"))
            .username(object.getStr("preferred_username"))
            .nickname(object.getStr("nickname"))
            .avatar(object.getStr("picture"))
            .email(object.getStr("email"))
            .token(authToken)
            .source(source.toString())
            .build();
    }
    @Override
    protected String doGetUserInfo(AuthToken authToken) {
        return new HttpUtils(config.getHttpConfig()).get(source.userInfo(), null, new HttpHeader()
            .add("Content-Type", "application/json")
            .add("Authorization", "Bearer " + authToken.getAccessToken()), false).getBody();
    }
    @Override
    public String authorize(String state) {
        return UrlBuilder.fromBaseUrl(super.authorize(state))
            .queryParam("scope", StrUtil.join("%20", config.getScopes()))
            .build();
    }
    public static void checkResponse(Dict object) {
        // oauth/token éªŒè¯å¼‚常
        if (object.containsKey("error")) {
            throw new AuthException(object.getStr("error_description"));
        }
        // user éªŒè¯å¼‚常
        if (object.containsKey("message")) {
            throw new AuthException(object.getStr("message"));
        }
    }
}
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/topiam/AuthTopiamSource.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,51 @@
package org.dromara.common.social.topiam;
import me.zhyd.oauth.config.AuthSource;
import me.zhyd.oauth.request.AuthDefaultRequest;
/**
 * Oauth2 é»˜è®¤æŽ¥å£è¯´æ˜Ž
 *
 * @author xlsea
 * @since 2024-01-06
 */
public enum AuthTopiamSource implements AuthSource {
    /**
     * æµ‹è¯•
     */
    TOPIAM {
        /**
         * æŽˆæƒçš„api
         */
        @Override
        public String authorize() {
            return AuthTopIamRequest.SERVER_URL + "/oauth2/auth";
        }
        /**
         * èŽ·å–accessToken的api
         */
        @Override
        public String accessToken() {
            return AuthTopIamRequest.SERVER_URL + "/oauth2/token";
        }
        /**
         * èŽ·å–ç”¨æˆ·ä¿¡æ¯çš„api
         */
        @Override
        public String userInfo() {
            return AuthTopIamRequest.SERVER_URL + "/oauth2/userinfo";
        }
        /**
         * å¹³å°å¯¹åº”çš„ AuthRequest å®žçŽ°ç±»ï¼Œå¿…é¡»ç»§æ‰¿è‡ª {@link AuthDefaultRequest}
         */
        @Override
        public Class<? extends AuthDefaultRequest> getTargetClass() {
            return AuthTopIamRequest.class;
        }
    }
}
ruoyi-common/ruoyi-common-social/src/main/java/org/dromara/common/social/utils/SocialUtils.java
@@ -11,6 +11,7 @@
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.maxkey.AuthMaxKeyRequest;
import org.dromara.common.social.topiam.AuthTopIamRequest;
/**
 * è®¤è¯æŽˆæƒå·¥å…·ç±»
@@ -38,7 +39,8 @@
        AuthConfig.AuthConfigBuilder builder = AuthConfig.builder()
            .clientId(obj.getClientId())
            .clientSecret(obj.getClientSecret())
            .redirectUri(obj.getRedirectUri());
            .redirectUri(obj.getRedirectUri())
            .scopes(obj.getScopes());
        return switch (source.toLowerCase()) {
            case "dingtalk" -> new AuthDingTalkRequest(builder.build(), STATE_CACHE);
            case "baidu" -> new AuthBaiduRequest(builder.build(), STATE_CACHE);
@@ -63,6 +65,7 @@
            case "wechat_mp" -> new AuthWeChatMpRequest(builder.build(), STATE_CACHE);
            case "aliyun" -> new AuthAliyunRequest(builder.build(), STATE_CACHE);
            case "maxkey" -> new AuthMaxKeyRequest(builder.build(), STATE_CACHE);
            case "topiam" -> new AuthTopIamRequest(builder.build(), STATE_CACHE);
            default -> throw new AuthException("未获取到有效的Auth配置");
        };
    }
script/sql/ry_vue_5.X.sql
@@ -21,7 +21,7 @@
    union_id           varchar(255)     default null    comment '用户的 unionid',
    scope              varchar(255)     default null    comment '授予的权限,部分平台可能没有',
    token_type         varchar(255)     default null    comment '个别平台的授权信息,部分平台可能没有',
    id_token           varchar(255)     default null    comment 'id token,部分平台可能没有',
    id_token           text             default null    comment 'id token,部分平台可能没有',
    mac_algorithm      varchar(255)     default null    comment '小米平台用户的附带属性,部分平台可能没有',
    mac_key            varchar(255)     default null    comment '小米平台用户的附带属性,部分平台可能没有',
    code               varchar(255)     default null    comment '用户的授权code,部分平台可能没有',