新聞中心
目前很多平臺都提供了單點(diǎn)登錄授權(quán)服務(wù)器功能,比如我們經(jīng)常用到的QQ登錄、微信登錄、新浪微博登錄、支付寶登錄等。如果我們自己的系統(tǒng)需要調(diào)用第三方登錄,那么我們就需要實(shí)現(xiàn)單點(diǎn)登錄客戶端,然后跟需要對接的平臺調(diào)試登錄SDK。JustAuth是第三方授權(quán)登錄的工具類庫,對接了國外內(nèi)數(shù)十家第三方登錄的SDK,我們在需要實(shí)現(xiàn)第三方登錄時,只需要集成JustAuth工具包,然后配置即可實(shí)現(xiàn)第三方登錄,省去了需要對接不同SDK的麻煩。??JustAuth官方提供了多種入門指南,集成使用非常方便。但是如果要貼合我們自有開發(fā)框架的業(yè)務(wù)需求,還是需要進(jìn)行整合優(yōu)化。下面根據(jù)我們的系統(tǒng)需求,從兩方面進(jìn)行整合:一是支持多租戶功能,二是和自有系統(tǒng)的用戶進(jìn)行匹配。

成都創(chuàng)新互聯(lián)公司一直在為企業(yè)提供服務(wù),多年的磨煉,使我們在創(chuàng)意設(shè)計,網(wǎng)絡(luò)營銷推廣到技術(shù)研發(fā)擁有了開發(fā)經(jīng)驗(yàn)。我們擅長傾聽企業(yè)需求,挖掘用戶對產(chǎn)品需求服務(wù)價值,為企業(yè)制作有用的創(chuàng)意設(shè)計體驗(yàn)。核心團(tuán)隊擁有超過十載以上行業(yè)經(jīng)驗(yàn),涵蓋創(chuàng)意,策化,開發(fā)等專業(yè)領(lǐng)域,公司涉及領(lǐng)域有基礎(chǔ)互聯(lián)網(wǎng)服務(wù)成都二樞服務(wù)器租用托管、app軟件開發(fā)公司、手機(jī)移動建站、網(wǎng)頁設(shè)計、網(wǎng)絡(luò)整合營銷。
一、JustAuth多租戶系統(tǒng)配置
GitEgg多租戶功能實(shí)現(xiàn)介紹
GitEgg框架支持多租戶功能,從多租戶的實(shí)現(xiàn)來講,目前大多數(shù)平臺都是在登錄界面輸入租戶的標(biāo)識來確定屬于哪個租戶,這種方式簡單有效,但是對于用戶來講體驗(yàn)不是很好。我們更希望的多租戶功能是能夠讓用戶無感知,且每個租戶有自己不同的界面展示。??
GitEgg在實(shí)現(xiàn)多租戶功能時,考慮到同一域名可以設(shè)置多個子域名,每個子域名可對應(yīng)不同的租戶。所以,對于多租戶的識別方式,首先是根據(jù)瀏覽器當(dāng)前訪問的域名或IP地址和系統(tǒng)配置的多租戶域名或IP地址信息進(jìn)行自動識別,如果是域名或IP地址存在多個,或者未找到相關(guān)配置時,才會由用戶自己選擇屬于哪個租戶。
自定義JustAuth配置文件信息到數(shù)據(jù)庫和緩存
在JustAuth的官方Demo中,SpringBoot集成JustAuth是將第三方授權(quán)信息配置在yml配置文件中的,對于單租戶系統(tǒng)來說,可以這樣配置。但是,對于多租戶系統(tǒng),我們需要考慮多種情況:一種是整個多租戶系統(tǒng)使用同一套第三方授權(quán),授權(quán)之后再由用戶選擇綁定到具體的租戶;另外一種是每個租戶配置自己的第三方授權(quán),更具差異化。??
出于功能完整性的考慮,我們兩種情況都實(shí)現(xiàn),當(dāng)租戶不配置自有的第三方登錄參數(shù)時,使用的是系統(tǒng)默認(rèn)自帶的第三方登錄參數(shù)。當(dāng)租戶配置了自有的第三方登錄參數(shù)時,就是使用租戶自己的第三方授權(quán)服務(wù)器。我們將JustAuth原本配置在yml配置文件中的第三方授權(quán)服務(wù)器信息配置在數(shù)據(jù)庫中,并增加多租戶標(biāo)識,這樣在不同租戶調(diào)用第三方登錄時就是相互隔離的。
1、JustAuth配置信息表字段設(shè)計
首先我們通過JustAuth官方Demojustauth-spring-boot-starter-demo 了解到JustAuth主要的配置參數(shù)為:
- JustAuth功能啟用開關(guān)。
- 自定義第三方登錄的配置信息。
- 內(nèi)置默認(rèn)第三方登錄的配置信息。
- Http請求代理的配置信息。
- 緩存的配置信息。
justauth:
# JustAuth功能啟用開關(guān)
enabled: true
# 自定義第三方登錄的配置信息
extend:
enum-class: com.xkcoding.justauthspringbootstarterdemo.extend.ExtendSource
config:
TEST:
request-class: com.xkcoding.justauthspringbootstarterdemo.extend.ExtendTestRequest
client-id: xxxxxx
client-secret: xxxxxxxx
redirect-uri: http://oauth.xkcoding.com/demo/oauth/test/callback
MYGITLAB:
request-class: com.xkcoding.justauthspringbootstarterdemo.extend.ExtendMyGitlabRequest
client-id: xxxxxx
client-secret: xxxxxxxx
redirect-uri: http://localhost:8443/oauth/mygitlab/callback
# 內(nèi)置默認(rèn)第三方登錄的配置信息
type:
GOOGLE:
client-id: xxxxxx
client-secret: xxxxxxxx
redirect-uri: http://localhost:8443/oauth/google/callback
ignore-check-state: false
scopes:
- profile
- openid
# Http請求代理的配置信息
http-config:
timeout: 30000
proxy:
GOOGLE:
type: HTTP
hostname: 127.0.0.1
port: 10080
MYGITLAB:
type: HTTP
hostname: 127.0.0.1
port: 10080
# 緩存的配置信息
cache:
type: default
prefix: 'demo::'
timeout: 1h
在對配置文件存儲格式進(jìn)行設(shè)計時,結(jié)合對多租戶系統(tǒng)的需求分析,我們需要選擇哪些配置是系統(tǒng)公共配置,哪些是租戶自己的配置。比如自定義第三方登錄的enum-class這個是需要由系統(tǒng)開發(fā)的,是整個多租戶系統(tǒng)的功能,這種可以看做是通用配置,但是在這里,考慮到后續(xù)JustAuth系統(tǒng)升級,我們不打算破壞原先配置文件的結(jié)構(gòu),所以我們?nèi)赃x擇各租戶隔離配置。??
我們將JustAuth配置信息拆分為兩張表存儲,一張是配置JustAuth開關(guān)、自定義第三方登錄配置類、緩存配置、Http超時配置等信息的表(t_just_auth_config),這些配置信息的同一特點(diǎn)是與第三方登錄系統(tǒng)無關(guān),不因第三方登錄系統(tǒng)的改變而改變;還有一張表是配置第三方登錄相關(guān)的參數(shù)、Http代理請求表(t_just_auth_source)。租戶和t_just_auth_config為一對一關(guān)系,和t_just_auth_source為一對多關(guān)系。
t_just_auth_config(租戶第三方登錄功能配置表)表定義:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_just_auth_config
-- ----------------------------
DROP TABLE IF EXISTS `t_just_auth_config`;
CREATE TABLE `t_just_auth_config` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '租戶id',
`enabled` tinyint(1) NULL DEFAULT NULL COMMENT 'JustAuth開關(guān)',
`enum_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '自定義擴(kuò)展第三方登錄的配置類',
`http_timeout` bigint(20) NULL DEFAULT NULL COMMENT 'Http請求的超時時間',
`cache_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '緩存類型',
`cache_prefix` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '緩存前綴',
`cache_timeout` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '緩存超時時間',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '創(chuàng)建時間',
`creator` bigint(20) NULL DEFAULT NULL COMMENT '創(chuàng)建者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新時間',
`operator` bigint(20) NULL DEFAULT NULL COMMENT '更新者',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT '是否刪除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '租戶第三方登錄功能配置表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
t_just_auth_sourc(租戶第三方登錄信息配置表)表定義:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_just_auth_source
-- ----------------------------
DROP TABLE IF EXISTS `t_just_auth_source`;
CREATE TABLE `t_just_auth_source` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`tenant_id` bigint(20) NOT NULL DEFAULT 0 COMMENT '租戶id',
`source_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方登錄的名稱',
`source_type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '第三方登錄類型:默認(rèn)default 自定義custom',
`request_class` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '自定義第三方登錄的請求Class',
`client_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '客戶端id:對應(yīng)各平臺的appKey',
`client_secret` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '客戶端Secret:對應(yīng)各平臺的appSecret',
`redirect_uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '登錄成功后的回調(diào)地址',
`alipay_public_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '支付寶公鑰:當(dāng)選擇支付寶登錄時,該值可用',
`union_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '是否需要申請unionid,目前只針對qq登錄',
`stack_overflow_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Stack Overflow Key',
`agent_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '企業(yè)微信,授權(quán)方的網(wǎng)頁應(yīng)用ID',
`user_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '企業(yè)微信第三方授權(quán)用戶類型,member|admin',
`domain_prefix` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '域名前綴 使用 Coding 登錄和 Okta 登錄時,需要傳該值。',
`ignore_check_state` tinyint(1) NOT NULL DEFAULT 0 COMMENT '忽略校驗(yàn)code state}參數(shù),默認(rèn)不開啟。',
`scopes` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '支持自定義授權(quán)平臺的 scope 內(nèi)容',
`device_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '設(shè)備ID, 設(shè)備唯一標(biāo)識ID',
`client_os_type` int(11) NULL DEFAULT NULL COMMENT '喜馬拉雅:客戶端操作系統(tǒng)類型,1-iOS系統(tǒng),2-Android系統(tǒng),3-Web',
`pack_id` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '喜馬拉雅:客戶端包名',
`pkce` tinyint(1) NULL DEFAULT NULL COMMENT ' 是否開啟 PKCE 模式,該配置僅用于支持 PKCE 模式的平臺,針對無服務(wù)應(yīng)用,不推薦使用隱式授權(quán),推薦使用 PKCE 模式',
`auth_server_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Okta 授權(quán)服務(wù)器的 ID, 默認(rèn)為 default。',
`ignore_check_redirect_uri` tinyint(1) NOT NULL DEFAULT 0 COMMENT '忽略校驗(yàn) {@code redirectUri} 參數(shù),默認(rèn)不開啟。',
`proxy_type` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Http代理類型',
`proxy_host_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 'Http代理Host',
`proxy_port` int(11) NULL DEFAULT NULL COMMENT 'Http代理Port',
`create_time` datetime(0) NULL DEFAULT NULL COMMENT '創(chuàng)建時間',
`creator` bigint(20) NULL DEFAULT NULL COMMENT '創(chuàng)建者',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新時間',
`operator` bigint(20) NULL DEFAULT NULL COMMENT '更新者',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT '是否刪除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '租戶第三方登錄信息配置表' ROW_FORMAT = DYNAMIC;
SET FOREIGN_KEY_CHECKS = 1;
2、使用GitEgg代碼生成工具生成JustAuth配置信息的CRUD代碼
我們將JustAuth配置信息管理的相關(guān)代碼和JustAuth實(shí)現(xiàn)業(yè)務(wù)邏輯的代碼分開,配置信息我們在系統(tǒng)啟動時加載到Redis緩存,JustAuth在調(diào)用時,直接調(diào)用Redis緩存中的配置。??
前面講過如何通過數(shù)據(jù)庫表設(shè)計生成CRUD的前后端代碼,這里不再贅述,生成好的后臺代碼我們放在gitegg-service-extension工程下,和短信、文件存儲等的配置放到同一工程下,作為框架的擴(kuò)展功能。
基礎(chǔ)配置:
第三方列表:
3、代碼生成之后,需要做初始化緩存處理,即在第三方配置服務(wù)啟動的時候,將多租戶的配置信息初始化到Redis緩存中。
- 初始化的CommandLineRunner類 InitExtensionCacheRunner.java。
/**
* 容器啟動完成加載資源權(quán)限數(shù)據(jù)到緩存
* @author GitEgg
*/
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Component
public class InitExtensionCacheRunner implements CommandLineRunner {
private final IJustAuthConfigService justAuthConfigService;
private final IJustAuthSourceService justAuthSourceService;
@Override
public void run(String... args) {
log.info("InitExtensionCacheRunner running");
// 初始化第三方登錄主配置
justAuthConfigService.initJustAuthConfigList();
// 初始化第三方登錄 第三方配置
justAuthSourceService.initJustAuthSourceList();
}
}
- 第三方登錄主配置初始化方法。
/**
* 初始化配置表列表
* @return
*/
@Override
public void initJustAuthConfigList() {
QueryJustAuthConfigDTO queryJustAuthConfigDTO = new QueryJustAuthConfigDTO();
queryJustAuthConfigDTO.setStatus(GitEggConstant.ENABLE);
ListjustAuthSourceInfoList = justAuthConfigMapper.initJustAuthConfigList(queryJustAuthConfigDTO);
// 判斷是否開啟了租戶模式,如果開啟了,那么角色權(quán)限需要按租戶進(jìn)行分類存儲
if (enable) {
Map> authSourceListMap =
justAuthSourceInfoList.stream().collect(Collectors.groupingBy(JustAuthConfigDTO::getTenantId));
authSourceListMap.forEach((key, value) -> {
String redisKey = AuthConstant.SOCIAL_TENANT_CONFIG_KEY + key;
redisTemplate.delete(redisKey);
addJustAuthConfig(redisKey, value);
});
} else {
redisTemplate.delete(AuthConstant.SOCIAL_CONFIG_KEY);
addJustAuthConfig(AuthConstant.SOCIAL_CONFIG_KEY, justAuthSourceInfoList);
}
}
private void addJustAuthConfig(String key, ListconfigList) {
MapauthConfigMap = new TreeMap<>();
Optional.ofNullable(configList).orElse(new ArrayList<>()).forEach(config -> {
try {
authConfigMap.put(config.getTenantId().toString(), JsonUtils.objToJson(config));
redisTemplate.opsForHash().putAll(key, authConfigMap);
} catch (Exception e) {
log.error("初始化第三方登錄失敗:{}" , e);
}
});
}
- 第三方登錄參數(shù)配置初始化方法。
/**
* 初始化配置表列表
* @return
*/
@Override
public void initJustAuthSourceList() {
QueryJustAuthSourceDTO queryJustAuthSourceDTO = new QueryJustAuthSourceDTO();
queryJustAuthSourceDTO.setStatus(GitEggConstant.ENABLE);
ListjustAuthSourceInfoList = justAuthSourceMapper.initJustAuthSourceList(queryJustAuthSourceDTO);
// 判斷是否開啟了租戶模式,如果開啟了,那么角色權(quán)限需要按租戶進(jìn)行分類存儲
if (enable) {
Map> authSourceListMap =
justAuthSourceInfoList.stream().collect(Collectors.groupingBy(JustAuthSourceDTO::getTenantId));
authSourceListMap.forEach((key, value) -> {
String redisKey = AuthConstant.SOCIAL_TENANT_SOURCE_KEY + key;
redisTemplate.delete(redisKey);
addJustAuthSource(redisKey, value);
});
} else {
redisTemplate.delete(AuthConstant.SOCIAL_SOURCE_KEY);
addJustAuthSource(AuthConstant.SOCIAL_SOURCE_KEY, justAuthSourceInfoList);
}
}
private void addJustAuthSource(String key, ListsourceList) {
MapauthConfigMap = new TreeMap<>();
Optional.ofNullable(sourceList).orElse(new ArrayList<>()).forEach(source -> {
try {
authConfigMap.put(source.getSourceName(), JsonUtils.objToJson(source));
redisTemplate.opsForHash().putAll(key, authConfigMap);
} catch (Exception e) {
log.error("初始化第三方登錄失?。簕}" , e);
}
});
}
4、引入JustAuth相關(guān)依賴jar包
- 在gitegg-platform-bom工程中引入JustAuth包和版本,JustAuth提供了SpringBoot集成版本justAuth-spring-security-starter,如果簡單使用,可以直接引用SpringBoot集成版本,我們這里因?yàn)樾枰鱿鄳?yīng)的定制修改,所以引入JustAuth基礎(chǔ)工具包。
······


咨詢
建站咨詢
