add 新增 JustAuth 整合 TopIam 单点登录

2.X
疯狂的狮子Li 1 year ago
parent 439a8edf9c
commit d04a6faa3c

@ -34,6 +34,13 @@ justauth:
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

@ -2,6 +2,8 @@ package org.dromara.common.social.config.properties;
import lombok.Data;
import java.util.List;
/**
*
*
@ -65,4 +67,9 @@ public class SocialLoginConfigProperties {
*/
private String serverUrl;
/**
*
*/
private List<String> scopes;
}

@ -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"));
}
}
}

@ -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";
}
/**
* accessTokenapi
*/
@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;
}
}
}

@ -11,6 +11,7 @@ import org.dromara.common.core.utils.SpringUtils;
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;
/**
*
@ -35,10 +36,11 @@ public class SocialUtils {
if (ObjectUtil.isNull(obj)) {
throw new AuthException("不支持的第三方登录类型");
}
final AuthConfig.AuthConfigBuilder builder = AuthConfig.builder()
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 @@ public class SocialUtils {
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配置");
};
}

@ -20,7 +20,7 @@ create table sys_social
union_id varchar2(255) default null,
scope varchar2(255) default null,
token_type varchar2(255) default null,
id_token varchar2(255) default null,
id_token varchar2(2000) default null,
mac_algorithm varchar2(255) default null,
mac_key varchar2(255) default null,
code varchar2(255) default null,

@ -20,7 +20,7 @@ create table sys_social
union_id varchar(255) default null::varchar,
scope varchar(255) default null::varchar,
token_type varchar(255) default null::varchar,
id_token varchar(255) default null::varchar,
id_token varchar(2000) default null::varchar,
mac_algorithm varchar(255) default null::varchar,
mac_key varchar(255) default null::varchar,
code varchar(255) default null::varchar,

@ -21,7 +21,7 @@ create table sys_social
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 varchar(2000) 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部分平台可能没有',

Loading…
Cancel
Save