这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
SPI扩展机制
1. 概述
当集成基础能力无法满足客户需求时,平台提供SPI扩展机制,用户可以在不影响上层使用的前提下,通过手写客开代码,实现统一身份认证、免登、单点登录、移动 App 接入、接口鉴权、基础能力厂商通道扩展等能力,解决个性化集成需求。
2. 能力架构
3. SPI 机制实现说明
3.1. spi jar 包项目开发并打包
下载帮助文档中对应功能 spi 示例的 demo 项目按需实现对应业务接口,并打包成 jar 包
3.2. 配置 jar 包动态加载必须的配置信息
将客开实现的 jar 包上传到私服或服务器本地, 配置到对应服务的配置中(nacos 或 yaml 文件)
配置完成后, 重启 spi jar包里实现的接口对应的项目即可
3.2.1 如果项目中配置了私服, 并通过私服管理扩展 jar 包的情况
验证 nacos 中 public 或项目中是否存在以下配置, 如果不存在则添加,如果存在则忽略
# public 配置确认
seeyon:
# 开启 spi 动态扩展的私服配置, 用于从私服里拉取扩展 jar 包
dynamic:
loader:
type: maven # 固定值
maven:
releaseUrl: release库地址
snapshotUrl: snapshot库地址
username: 账号
password: 密码
对应项目中的 nacos 或 yaml 配置文件配置内容
# 对应服务配置
seeyon:
spi:
enable: true # 固定值 true
spi-plugins:
# 上传到私服里的扩展 jar 包的 GAV(groupId / artifactId / version)坐标。 maven: 开头
# 固定格式 maven: 开头, 冒号后面没有空格, - 后面一个英文空格
- maven:com.seeyon,xxx-xxx-xxx,x.y.z
注意:
spi-plugins的值:- maven:com.seeyon,xxx-xxx-xxx,x.y.z
, 短横杠 后面 1 个英文空格, 前面 6
个英文空格
maven:xxx.xxx,xx-xx-xx,x.y.z
整体字符串中间 没有空格
所有缩进,以 两个英文空格 为标准, 不要使用 TAB 缩进
配置内容都是在 英文输入法 下配置,不要使用中文输入法
扩展 jar 包如果依赖外部 jar 包,也要将外部 jar 包对应的坐标配置到 seeyon.spi.spi-plugins
下
3.2.2 如果项目中未配置私服,通过服务器文件管理 jar 包的情况
对应服务 nacos 配置(Maven是有私服的,file是没有私服的)
# 对应服务配置
seeyon:
spi:
enable: true # 固定值 true
spi-plugins:
# 固定格式: file: 开头, 冒号后面没有空格, - 后面一个英文空格
- file:/data/xxx/xxx.jar
注意:
- 两种配置根据项目情况取其一即可,jar包放到对应位置后,要确认jar包是否完整,对比下本地打的jar包大小,与服务器上的是否一致
- spi-plugins的值:
- file:/data/xxx/xxx.jar
, 短横杠 后面 1 个英文空格, 前面 6 个英文空格
file:/data/xxx/xxx.jar
整体字符串中间 没有空格
- 所有缩进,以 两个英文空格 为标准, 不要使用 TAB 缩进
- 配置内容都是在 英文输入法 下配置,不要使用中文输入法
- 扩展 jar 包如果依赖外部 jar 包,也要将外部 jar 包对应的坐标配置到
seeyon.spi.spi-plugins
下
3.3. 视频讲解
4. xxxSpiUtil 工具类说明
工具类位于对应项目 api 包中的 util 下, 主要提供 spi 扩展 jar 包里的类的实例化获取, spring 管理的 bean的获取、调用、nacos或yaml中的配置信息获取功能
其中 ctp-user-api jar 包中还包含 request 对象的获取功能
4.1. 工具类介绍
以 ctp-user-api 中的 CtpUserSpiUtils 为例
@CtpUserComment("spi 扩展包工具类,可以获取 bean 的实例,通过配置 key 获取 nacos 或 yaml 配置内容等")
public class CtpUserSpiUtils {
@CtpUserComment("获取指定类的单例实例")
public static <T> T getInstance(Class<T> clazz) {
}
@CtpUserComment("获取获取被 spring 管理的指定类别的 Bean 对象")
public static <T> T getBean(Class<T> clazz) {
}
@CtpUserComment("获取指定名称和类型的 Bean 对象, 获取被 spring 管理的 bean 的对象")
public static <T> T getBean(String beanName, Class<T> requiredType) {
}
@CtpUserComment("调用指定 Bean 的指定方法并返回结果, beanName 是主服务中的 bean,jar 包中想用时可以通过此方法调用")
public static <T> T invokeBean(String beanName, String methodName, Object... params) {
}
@CtpUserComment("通过 key 获取属性配置值, 属性配置可以是 yaml 文件也可以是 nacos 配置")
public static String getPropertyByName(String key) {
}
@CtpUserComment("获取 request 对象")
public static HttpServletRequest getRequest() {
}
}
方法说明:
- getInstance(): 获取 spi jar包内的类的实例, 使用单例模式,保证每个类只被实例化一次。 注: 不会获取到 Spring 管理的 bean 的实例
- getBean(): 获取 spring 管理的 bean 的实例, 注: 不会获取到 spi jar包内的类的实例
- invokeBean(): 调用 spring 管理的 bean 的方法
- getPropertyByName(): 获取 nacos 或 yaml 配置文件中的配置信息
- getRequest(): http 的 request 对象
5. 注意事项
5.1. 配置完spi jar包重启项目失败
排查:日志搜索SPIJar || 动态加载spi的插件 查看原因
tail -n 10000 xxx-info.log | grep -C 50 '日志搜索SPIJar'
5.2. 配置信息不对(配置格式层级不对)
举例如下
根据实际上传的版本来,比如此例中应该是
5.3. 配置中含有中文的空格,字符导致
字符-及后面的空格等全部要求是英文才可以,配置手写重新敲一遍配置
6、能力清单
1 - 统一身份认证
支持通过SPI扩展机制,接入三方统一身份认证系统。
1. 概述
使用三方认证中心进行统一身份认证, 在登录 v8 系统时, 会先跳转到三方认证中心进行登录, 三方认证中心登录成功后, 重定向 v8
目标地址,完成系统登录过程。
2. spi 接入导图
统一身份认证时序图
3. 接入步骤
3.1. demo工程下载
注意:使用前请依赖平台 ctp-user-api 对应的版本进行扩展开发
cip-spi-user-sso-thirdauth.zip
3.2. 配置与使用
3.2.1. 重定向到 v8 系统的域名配置
主要配置认证中心授信信息, 如 clientId, clientSecret 等。
注意:以下配置需要在public下,其中dev.seeyonv8.com为V8平台域名,使用时请更换为对应环境域名或ip端口
yaml 格式配置:
seeyon:
system:
domain: dev.seeyonv8.com
properties 格式配置
seeyon.system.domain=dev.seeyonv8.com
3.2.2. 重要:开启三方认证中心开关
在ctp-user微服务下
yaml 格式配置:
开起spi认证,其中spisso为固定值
seeyon:
user:
authenticationType: spisso
认证类型配置,其中thirdauth为spi扩展的认证类型,对应spi代码中的类型,例如:maxkey、zhuyun等
seeyon:
spisso:
ssoType: thirdauth
配置与三方认证中心的授信信息
seeyon:
thirdauth:
clientId: xxx
clientSecret: xxx
properties 格式配置
开起spi认证
seeyon.user.authenticationType=spisso
认证类型配置
seeyon.spisso.ssoType=thirdauth
认证配置
seeyon.thirdauth.clientId=xxx
seeyon.thirdauth.clientSecret=xxx
3.3. spi jar 打包并部署
参考 SPI扩展
配置完成后, 重启 ctp-user 服务
3.4. 测试方式
说明:免登地址拼接规则:
工程开发完成并发布后,在URL中输入【服务域名】/main/portal,点击回车/访问后,浏览器自动重定向到统一身份认证中心认证页,输入认证中心账号密码后,成功进入V8平台首页,则标识工程正确,且连接无误。
3.5. 异常跟踪
3.6. 内容校验
浏览器地址输入:<domain>/service/ctp-user/api/sso-config
确认内容:
jar 包里的 clientId 与 ctp-user 里的关键配置是否一致
如何使用私服仓库, 确认仓库地址、账号密码是否配置
确认登录成功后的重定向域名是否正确
spi 是否配置成功
spi jar里的 spring.factories 配置是否正确
4. 工程核心接口说明
4.1. 登录
说明:URL输入【V8首页地址】,或者三方门户点击进入【V8首页地址】时,网关拦截跳转到三方统一身份认证页,
如果未登录则使用账号密码登录,成功登录后跳转到【V8首页地址】,并携带授权code;
如果已经登陆,无需输入账号密码,成功登录后跳转到【V8首页地址】,并携带授权code;
后台解析授权code,换取用户信息,V8登录成功。
【V8首页地址】可以是V8任何一个页面,除了登录页“/login”。
/**
* 三方认证 sso 登录地址
*
* @param request
* @param encodeRedirectUrl url encode 后的重定向地址,三方认证登录成功后的跳转地址
* encodeRedirectUrl: http://dev.seeeyon.com/thirdauth-login/aaa?url=/main/protal
* @return 三方认证中心登录地址
*/
@Override
public String getSsoLoginUrl(HttpServletRequest request, String encodeRedirectUrl) {
String thirdLoginUrl = "http://xxx.sso.com/login?redirectUrl=" + encodeRedirectUrl;
log.info("跳转到三方认证中心地址:{}", thirdLoginUrl);
return thirdLoginUrl;
}
/**
* 从三方认证接口中获取用户信息
*
* @param request
* @param encodeRedirectUrl url encode 后的重定向地址,三方认证登录成功后的跳转地址
* @return CtpUserSpiLoginUserInfoDto 三方用户信息 DTO
* @throws CtpUserSpiSsoException 三方认证登录失败时, 由 v8 自定义页面显示的异常信息
*/
@Override
public CtpUserSpiLoginUserInfoDto getUserLoginInfo(HttpServletRequest request, String encodeRedirectUrl) throws CtpUserSpiSsoException {
// 通过配置拿到三方 clientId
String clientId = ThirdauthSsoAuthConstants.NACOS_CLIENT_ID;
// 调用内部方法进行逻辑处理
thirdauthSsoAuthHandler.test();
// 调用三方认证接口,获取用户信息
// 获取三方认证中心登录后,追加的 code 的值
String code = request.getParameter(getRequestParaKey());
// 通过 code 获取 token
// eg. String token = getTokenByCode(code);
// 通过 token 获取用户登录名
// eg. String loginName = getLoginNameByToken(token);
// // [按需实现] 如果需要缓存三方认证中心的 token,则需要封装下面对象
// CtpUserSpiThirdTokenDto ctpUserSpiThirdTokenDto = CtpUserSpiThirdTokenDto.builder()
// .thirdToken("123456") // 三方认证中心的 token
// .expired(3600L) // 过期时间_秒 可空,如果为空则默认 7 天
// .extData(new HashMap<>()) // [按需实现] 扩展参数, 下面刷新三方 token 方法 refreshThirdauthTokenByConfig 中的 thirdauthTokenConfigMap 会将这个扩展参数传入
// .build();
return CtpUserSpiLoginUserInfoDto.builder()
// 用于登录的用户信息, 下面五个参数只选择一下赋值即可, 赋值的参数的值要与 v8系统中的对应的值一致
.thirdLoginName("zhangsan")
// .thirdUserId("123456")
// .thirdMobile("13900000001")
// .thirdUserEmail("abc@abc.com")
// .thirdUserCode("usercode")
//用于登录的用户信息, 上面五个参数只选择一下赋值即可
// 如果用户有租户条件
// .tenantType("code").tenantData(tenantCode) // or .tenantType("id").tenantData("-1")
// .thirdUserInfoJson("{\"name\":\"张三\"}") // [按需实现] 待缓存的三方用户信息, 下面登录方法 thirdauthSsoLogout 中将这个参数传入
// .ctpUserSpiThirdTokenDto(ctpUserSpiThirdTokenDto) // 如果需要缓存并刷新三方 token 信息,则封装这个参数
.build();
}
4.2. 三方认证Token持久化
说明:登录成功后,V8按需将三方持久化授权token写入根域名cookie中。
/**
* [按需实现] 三方认证中心 token 中否保存到 cookie中,如果需要, 则返回 cookie 的 key
*
* @return 保存三方 token 的 cookie 的 key 的值
*/
@Override
public String get4aTokenKey() {
return "4a-token";
}
4.3. 短连接
说明:三方认证成功后,重定向地址太长时使用短连接解决,支持两种模式:
1、紧凑模式:【V8访问域名】/oauth/home/sl/abc;
2、拼接模式:【V8访问域名】/oauth/home?mappingId=abc
/**
* [按需实现] 登录三方成功后的重定向地址是否使用短链接, 如果不需要使用短链接,不用实现或直接返回 null
*
* @return ShortLinkModeEnum 短链接模式<br/>
* ShortLinkModeEnum#COMPACT_MODE: 紧凑模式, eg: domain/path/sl/xxx。<br/>
* ShortLinkModeEnum#SPLICING_MODE: 拼接模式, eg: domain/path?mappingId=xxx
* 如果为 null,则不使用短链接
*/
@Override
public ShortLinkModeEnum shortLinkMode() {
return null;
}
4.4. Token同步刷新
说明:随V8 用户认证token刷新动作,按需同步刷新三方持久化授权token三方Token。
/**
* [按需实现] 刷新三方认证中心的 token
*
* @param thirdToken 三方认证中心 token
* @param thirdTokenConfigMap 三方认证中心 token 配置
* @return CtpUserSpiThirdTokenDto 三方认证中心 token DTO 包含 token 信息和过期时间
*/
@Override
public CtpUserSpiThirdTokenDto refreshThirdTokenByConfig(String thirdToken, Map<String, Object> thirdTokenConfigMap) {
return null;
}
4.5. 退出
说明:v8用户Token单独失效退出(通过API退出), 三方Token单独失效退出(通过API退出,页面重定向退出)
支持两个Token同步失效退出
/**
* [按需实现] 三方登出重定向地址, 三方认证中心可通过此地址进行用户登录操作,如果没有此接口,则不用实现
*
* @return url encode 后的登出后的重定向地址
*/
@Override
public String getEncodeLogoutRedirectUrl() {
return null;
}
/**
* [按需实现] 三方登出后台逻辑
*
* @param request
* @param thirdUserInfoJson
*/
@Override
public void thirdSsoLogout(HttpServletRequest request, String thirdUserInfoJson) {
}
4.6. 用户登录报错时,跳转到自定义错误页
说明:免登失败时,自动跳转到自定义错误页,支持自定义错误信息可视
4.7. Nacos配置定义、获取值
说明:例如应用ID、秘钥、访问地址等跨环境需要变更参数,可以在nacos配置文件中维护
nacos位置:ctp-user
nacos参数值获取:需要通过工具类获取
String clientId = CtpUserSpiUtils.getPropertyByName("seeyon.thirdauth.clientId");
String clientSecret = CtpUserSpiUtils.getPropertyByName("seeyon.thirdauth.clientSecret");
5. 注意事项
无
2 - 免登-中间页模式
支持三方异构系统免登进入COP平台SPI扩展能力。不支持免登地址中携带自定义参数
1. 概述
三方异构系统通过中间页免登地址(地址中包含 v8 目标地址, 用户信息对应的随机值 code)
登录的 v8 目标地址: 中间页免登地址中的 v8 目标地址
登录的 v8 系统的用户信息: 通过 中间页免登地址中的用户随机值 code 查询到的用户信息, 同时 v8 系统中也要存在的用户
2. 接入导图
说明:有三方系统免登进入V8
3. 接入步骤
3.1. 工程下载
cip-spi-user-avoid-thirdavoid.zip
3.2. Nacos配置【按需】
注意:需要再ctp-user微服务下
yaml 格式配置:
seeyon:
thirdauth:
clientId: xxx
clientSecret: xxx
properties 格式配置
seeyon.thirdauth.clientId=xxx
seeyon.thirdauth.clientSecret=xxx
3.3. 工程开发
开发过程请参考【场景/方法说明】
3.4. spi jar 打包并部署
参考 SPI扩展
配置完成后, 重启 ctp-user 服务
3.5. 测试方式
说明:免登地址拼接规则:
/oauth/home
?mobile=%2Fmain-mobile%2Fportal # url encode 后重定向地址
&web=%2Fmain%2Fportal # url encode 后重定向地址
&businessType=outsider # 固定值
&type=thirdavoid # 约定的唯一类型
&dynamicField=code # 追加的 code 的 key 的值,如追加 code 这里为 code, 追加 ticket 这里值为 ticket
&code=2403832009216967675 # 三方追加的值
3.6. 内容校验
浏览器地址输入:<domain>/service/ctp-user/api/sso-config
通过免登地址,登录 A 账号查看待办, 后, 再打开 B 账号的待办, 不会切换账号
端: web
解决方法: ctp-user nacos配置
yaml 格式配置:
seeyon:
avoid:
clearCookieTypes:
- cscc # 类型1
- pccscc # 类型2
properties 格式配置:
seeyon.avoid.clearCookieTypes[0]=cscc
seeyon.avoid.clearCookieTypes[1]=pccscc
4. 场景/方法说明
4.1. 从免登地址中获取信息(Request)
说明:上游系统在URL请求时,携带授权信息/加密用户信息,COP平台拦截信息并模拟登陆场景。
免登地址拼接规则:
免登地址实例:
/oauth/home
?mobile=%2Fmain-mobile%2Fportal # url encode 后重定向地址
&web=%2Fmain%2Fportal # url encode 后重定向地址
&businessType=outsider # 固定值
&type=thirdavoid # 约定的唯一类型
&dynamicField=code # 追加的 code 的 key 的值,如追加 code 这里为 code, 追加 ticket 这里值为 ticket
&code=2403832009216967675 # 三方追加的值
/**
* 从请求中提取参数并获取用户信息
*
* @param code 三方追加的 code 的值
* @param extData 三方追加的扩展参数
* @return 用户属性信息
*/
@Override
public CtpAvoidLoginUserInfoDto getUserInfo(String code, Map<String, String> extData) {
log.info("从请求中提取参数并获取用户信息, code:{}", code);
// 调用内部方法进行逻辑处理
thirdavoidSsoHandler.test();
// [按需实现] 获取 request 对象
HttpServletRequest request = CtpUserSpiUtils.getRequest();
// 从 request 中获取想要的参数
request.getParameter("xxx");
// 通过 code 获取 token
// eg. String token = getTokenByCode(code);
// 通过 token 获取用户登录名
// eg. String loginName = getLoginNameByToken(token);
// // [按需实现] 免登成功后重定向地址, 如果不配置, 则默认跳转至打开免登时的目标地址
// CtpUserSpiRedirectUrlDto ctpUserSpiRedirectUrlDto = CtpUserSpiRedirectUrlDto.builder()
// .webRedirectUrl("/main/portal") // web 重定向地址
// .mobileRedirectUrl("/main-mobile/portal") // mobile 重定向地址
// .build();
// // [按需实现] 缓存免登后保存的三方 token
// CtpUserSpiThirdTokenDto ctpUserSpiThirdTokenDto = CtpUserSpiThirdTokenDto.builder()
// .thirdToken("xxx") // 待缓存的三方 token
// .expired(null) // 过期时间_秒
// .extData(new HashMap<>()) // 扩展参数
// .build();
// 返回用户信息、等缓存的三方认证 token、重定向地址
return CtpAvoidLoginUserInfoDto.builder()
// 用于登录的用户信息, 下面五个参数只选择一下赋值即可, 赋值的参数的值要与 v8系统中的对应的值一致
.thirdLoginName("zhangsan")
// .thirdUserId("123456")
// .thirdMobile("13900000001")
// .thirdUserEmail("abc@abc.com")
// .thirdUserCode("usercode")
//用于登录的用户信息, 上面五个参数只选择一下赋值即可
// [按需实现] 登录用户的租户信息
//.tenantType() // 租户数据类型:code / id
//.tenantData() // 与 tenantType 对应, 租户信息的值
// // [按需实现] 待缓存免登后保存的三方 token
// .ctpUserSpiThirdTokenDto(ctpUserSpiThirdTokenDto) // 三方认证 token
// [按需实现] 免登成功后重定向地址
//.ctpUserSpiRedirectUrlDto(ctpUserSpiRedirectUrlDto); // 免登成功后重定向地址
.build();
}
注: 不支持获取自定义追加的参数, 除了通过 dynamicField
定义人参数 key 外, 其它追加的参数无法获取
4.2. 三方认证Token持久化
说明:三方授权Token需要COP平台负责持久化存储,包含写入根域名、写入缓存、写入Redis等场景。
// // [按需实现] 缓存免登后保存的三方 token
// CtpUserSpiThirdTokenDto ctpUserSpiThirdTokenDto = CtpUserSpiThirdTokenDto.builder()
// .thirdToken("xxx") // 待缓存的三方 token
// .expired(null) // 过期时间_秒
// .extData(new HashMap<>()) // 扩展参数
// .build();
4.3. 三方Token自动刷新(定时)
说明:三方授权Token定时失效,需要定时使用原始Token换取新的Token场景。
/**
* 刷新三方 token
*
* @param thirdTokenDto 三方 token 信息
* @return 三方 token 保存 DTO
*/
@Override
public CtpUserSpiThirdTokenDto doRefreshToken(ThirdTokenDto thirdTokenDto) {
return CtpAvoidLoginMiddlePageProviderService.super.doRefreshToken(thirdTokenDto);
}
4.4. 自定义5元素用户标识
说明:三方异构系统用户匹配COP平台用户,支持手机号码、邮箱、登录名、用户编码、UserID任一字段值匹配免登。
// 返回用户信息、等缓存的三方认证 token、重定向地址
return CtpAvoidLoginUserInfoDto.builder()
// 用于登录的用户信息, 下面五个参数只选择一下赋值即可, 赋值的参数的值要与 v8系统中的对应的值一致
.
thirdLoginName("zhangsan")
// .thirdUserId("123456")
// .thirdMobile("13900000001")
// .thirdUserEmail("abc@abc.com")
// .thirdUserCode("usercode")
//用于登录的用户信息, 上面五个参数只选择一下赋值即可
// [按需实现] 登录用户的租户信息
//.tenantType() // 租户数据类型:code / id
//.tenantData() // 与 tenantType 对应, 租户信息的值
// // [按需实现] 待缓存免登后保存的三方 token
// .ctpUserSpiThirdTokenDto(ctpUserSpiThirdTokenDto) // 三方认证 token
// [按需实现] 免登成功后重定向地址
//.ctpUserSpiRedirectUrlDto(ctpUserSpiRedirectUrlDto); // 免登成功后重定向地址
.
build();
4.5. Nacos配置定义、获取值
说明:例如应用ID、秘钥、访问地址等跨环境需要变更参数,可以在nacos配置文件中维护
nacos位置:ctp-user
nacos参数值获取:需要通过工具类获取
CtpUserSpiUtils.getProperjavatyByName("seeyon.thirdavoid.clientId");
4.6. 日志查询
ctp-user.info 日志下, 搜索关键字 third dto
, 通过入口查询该次请求的 traceId, 再根据 traceId 查询整个链路处理情况
5. 注意事项
无
3 - 免登-中间页扩展模式
支持三方异构系统免登进入COP平台SPI扩展能力。支持免登地址中携带自定义参数
1. 概述
三方异构系统通过中间页免登地址(地址中包含 v8 目标地址, 用户信息对应的随机值 code, 以及自定义参数)
登录的 v8 目标地址: 中间页免登地址中的 v8 目标地址
登录的 v8 系统的用户信息: 通过 中间页免登地址中的用户随机值 code 查询到的用户信息, 同时 v8 系统中也要存在的用户
2. 接入导图
说明:有三方系统免登进入V8
3. 接入步骤
3.1. Nacos配置【按需】
注意:需要再ctp-user微服务下
yaml 格式配置:
seeyon:
thirdauth:
clientId: xxx
clientSecret: xxx
properties 格式配置
seeyon.thirdauth.clientId=xxx
seeyon.thirdauth.clientSecret=xxx
3.3. 工程开发
开发过程请参考【场景/方法说明】
3.4. spi jar 打包并部署
参考 SPI扩展
配置完成后, 重启 ctp-user 服务
3.5. 测试方式
说明:免登地址拼接规则:
/oauth/avoid
?sydata={"c": "thirdavoid","w":"/main/portal","m":"/main-mobile/portal"} # 固定格式。 c的值:约定的唯一类型, w:web端重定向地址,m:手机端重定向地址
&a=a # 自定义参数 a
&b=b # 自定义参数 a
&... # 自定义参数... 随意增加, 最大不超过100个
3.6. 强制重新登录配置
通过免登地址,登录 A 账号查看待办, 后, 再打开 B 账号的待办, 默认不会切换账号, 可以通过下面配置, 强制重新登录。
解决方法: ctp-user nacos配置
yaml 格式配置:
seeyon:
avoid:
clearCookieTypes:
- cscc # 类型1
- pccscc # 类型2
properties 格式配置:
seeyon.avoid.clearCookieTypes[0]=cscc
seeyon.avoid.clearCookieTypes[1]=pccscc
4. 场景/方法说明
4.1. 从免登地址中获取信息(Request)
说明:上游系统在URL请求时,携带授权信息/加密用户信息,COP平台拦截信息并模拟登陆场景。
@Override
public CtpAvoidLoginUserInfoDto getUserInfo(CtpUserSpiAvoidLoginClientModeDto avoidLoginClientModeDto) {
// 所有 url 中追加的自定义参数, 都可以通过 extData 里获取
Map<String, String> extData = avoidLoginClientModeDto.getExtData();
// 通过 code 获取 token
// eg. String token = getTokenByCode(code);
// 通过 token 获取用户登录名
// eg. String loginName = getLoginNameByToken(token);
// // [按需实现] 免登成功后重定向地址, 如果不配置, 则默认跳转至打开免登时的目标地址
// CtpUserSpiRedirectUrlDto ctpUserSpiRedirectUrlDto = CtpUserSpiRedirectUrlDto.builder()
// .webRedirectUrl("/main/portal") // web 重定向地址
// .mobileRedirectUrl("/main-mobile/portal") // mobile 重定向地址
// .build();
// // [按需实现] 缓存免登后保存的三方 token
// CtpUserSpiThirdTokenDto ctpUserSpiThirdTokenDto = CtpUserSpiThirdTokenDto.builder()
// .thirdToken("xxx") // 待缓存的三方 token
// .expired(null) // 过期时间_秒
// .extData(new HashMap<>()) // 扩展参数
// .build();
// 返回用户信息、等缓存的三方认证 token、重定向地址
return CtpAvoidLoginUserInfoDto.builder()
// 用于登录的用户信息, 下面五个参数只选择一下赋值即可, 赋值的参数的值要与 v8系统中的对应的值一致
.thirdLoginName("zhangsan")
// .thirdUserId("123456")
// .thirdMobile("13900000001")
// .thirdUserEmail("abc@abc.com")
// .thirdUserCode("usercode")
//用于登录的用户信息, 上面五个参数只选择一下赋值即可
// [按需实现] 登录用户的租户信息
//.tenantType() // 租户数据类型:code / id
//.tenantData() // 与 tenantType 对应, 租户信息的值
// // [按需实现] 待缓存免登后保存的三方 token
// .ctpUserSpiThirdTokenDto(ctpUserSpiThirdTokenDto) // 三方认证 token
// [按需实现] 免登成功后重定向地址
//.ctpUserSpiRedirectUrlDto(ctpUserSpiRedirectUrlDto); // 免登成功后重定向地址
.build();
}
4.5. Nacos配置定义、获取值
说明:例如应用ID、秘钥、访问地址等跨环境需要变更参数,可以在nacos配置文件中维护
nacos位置:ctp-user
nacos参数值获取:需要通过工具类获取
CtpUserSpiUtils.getProperjavatyByName("seeyon.thirdavoid.clientId");
5. 注意事项
无
4 - 单点登录
支持通过SPI扩展机制,扩展集成应用免登中的单点登录模式。
1、概述
单点登录场景:
- 点击V8菜单跳转三方系统。
- 点击三方栏目更多跳转三方系统。
- 点击通过集成应用同步过来的三方系统待办、消息,跳转至三方系统。
2、接入导图
3、接入步骤
3.1、demo工程下载
cip-connector-sso-template.zip
<parent>
<groupId>com.seeyon</groupId>
<artifactId>boot</artifactId>
<version>3.10.1</version>
</parent>
<properties>
<platform.version>3.10.1</platform.version>
</properties>
<dependencies>
<dependency>
<groupId>com.seeyon</groupId>
<artifactId>cip-connector-api</artifactId>
<version>${platform.version}</version>
</dependency>
</dependencies>
3.2. spi jar 打包并部署
参考 SPI扩展
注意:请在cip-connector微服务nacos配置文件中配置参数
上传完后需要重启cip-connector完成动态加载
3.3、工程开发
注意:每个项目下载工程并开发时,请优先修改工程名称,工程名遵守 cip-connector-auth-项目标识
开发过程请参考【场景/方法说明】
4、工程核心接口说明
4.1、定义单点登录英文表示
注意:该名称不能与其他名称重复,否则不会载入
/**
* 获取名称
* 需要保证名称唯一,名称+SecurityService 为当前类名称
* @return
*/
String getName();
4.2、定义单点登录中文描述
/**
* 获取描述
* @return
*/
String getTypeCaption();
4.3、定义前端可视化配置参数
/**
* 获取页面json语句
* @return
*/
String getPageJson();
4.3.1、字段说明:
{
"caption": "标准认证-CAS", //单点登录类型(下拉框名称)(select的中文值)
"type": "cas", //单点登录类型(下拉框值)(select对应的英文key)
"extensionProperties": //扩展参数
[
{
"colProps": //栅格化布局
{
"span": 12 //栅格化布局值
},
"componentType": "Input", //antd组件<br />标签名称
"componentProps": //扩展属性
{
"placeholder": "请输入" //select的placeholder提示
},
"validateFirst": true,
"rules": // 校验规则,<br/>参考antd表单的rules
[
{
"required": true,
"message": "请输入跳转地址"
},
{
"pattern": "^[^\\s]*$",
"message": "禁止输入空格"
},
{
"type": "string",
"max": 255,
"message": "最多255个字符"
}
],
"caption": "跳转地址", // 自定义名称
"defaultValue": "", //默认值,非必填
"name": "defaultJumpUrl"
}
]
}
4.3.3、效果实例:
4.4、根据原始请求地址拼接单点登录地址
/**
* 登录
* @param url 外部想跳转到的地址
* @param json 页面传递的数据
* @param userMap 用户信息map
* @param clientType 跳转类型(pc,移动)
*/
String login(String url, String json, Map<String,Object> userMap, SsoClientTypeEnum clientType
, Map<String, Object> extendParams
);
入参说明:
-
url: 外部传过来的想要跳转的特定地址
-
json: 前端页面配置的参数
-
userMap: 用户映射信息和用户映射自定义配置的参数
- innerUserId: 内部用户ID
- innerUserName: 内部用户名称
- innerUserCODE: 内部用户编号
- outerUser: 外部用户账户
- outerUserId: 外部用户ID
- innerUserLoginName: 内部用户登录名
- innerUserEmail: 内部用户邮箱
- innerUserPhone: 内部用户手机号
- innerUserOfficeNumber: 内部用户办公电话
- innerUserBankAccount: 内部用户银行账户
- innerUserOrgId: 内部用户组织编号
-
clientType: 类型(pc,phone)
-
extendParams: 外部传递过来的扩展参数
注意:按照3.3配置完成后,json获取的数据结构示例为:
-
{
"type": "xdHr",
"loginType": "PERSON_ID",
"account": "admin",
"password": "123456",
"ssoUrl": "http://www.login.com",
"defaultJumpUrl": "http://www.jump.com"
}
5、注意事项
无
5 - 移动插件
支持通过SPI扩展机制,扩展移动插件(移动管理-移动插件)。
1、概述
移动插件场景
1.V8应用接入三方APP工作台中,例如企业微信、钉钉、飞书等。
2.点击工作台应用图标免登进入V8应用。
3.V8产生的消息推送至三方APP。
4.V8组织人员信息同步至三方APP(可选)。
2、接入导图
3、接入步骤
3.1、demo工程下载
cip-spi-mobile-demo.zip
<parent>
<groupId>com.seeyon</groupId>
<artifactId>boot</artifactId>
<version>3.10.1</version>
</parent>
<properties>
<platform.version>3.10.1</platform.version>
</properties>
<dependencies>
<dependency>
<groupId>com.seeyon</groupId>
<artifactId>cip-connector-api</artifactId>
<version>${platform.version}</version>
</dependency>
</dependencies>
3.2. spi jar 打包并部署
参考 SPI扩展
注意:请在cip-connector微服务nacos配置文件中配置参数
上传完后需要重启cip-connector完成动态加载
3.3、工程开发
注意:每个项目下载工程并开发时,请优先修改工程名称,工程名遵守 cip-mobile-plugin-项目标识
开发过程请参考【场景/方法说明】
4、工程核心接口说明
1.必要条件,修改自定义类型
5、注意事项
6 - 接口鉴权
支持通过SPI扩展机制,扩展集成应用接口中的接口鉴权模式(集成应用-接口-安全认证)。
1、概述
接口鉴权场景:
集成应用中调用的三方接口需要前置认证的情况,例如先调用认证接口token,调用其他业务接口时,讲token放到请求头中。
2、接入导图
3、接入步骤
3.1、Demo工程下载
cip-connector-auth-template.zip
注意事项:
1.pom中的版本号要与项目当前版本保持一致,分别为boot版本、cip-connector-api版本
<parent>
<groupId>com.seeyon</groupId>
<artifactId>boot</artifactId>
<version>3.10.1</version>
</parent>
<properties>
<platform.version>3.10.1</platform.version>
</properties>
<dependencies>
<dependency>
<groupId>com.seeyon</groupId>
<artifactId>cip-connector-api</artifactId>
<version>${platform.version}</version>
</dependency>
</dependencies>
3.2. spi jar 打包并部署
参考 SPI扩展
上传完后需要重启cip-connector完成动态加载
3.3、工程开发
注意:每个项目下载工程并开发时,请优先修改工程名称,工程名遵守 cip-connector-auth-项目标识
4、工程核心接口说明
/**
* 认证请求(核心)
* @param authenticationDto 安全数据
* authId: 该安全认证在数据库中id
* detailId: 动作id,外部正在执行的动作id
* json: 页面配置动态数据,自行转换对应dto或者map
* params: 请求参数
* user: 当前登录人用户信息(包含用户映射配置信息)
* innerUserId: 内部用户ID
* innerUserName: 内部用户名称
* innerUserCODE: 内部用户编号
* outerUser: 外部用户账户
* outerUserId: 外部用户ID
* innerUserLoginName: 内部用户登录名
* innerUserEmail: 内部用户邮箱
* innerUserPhone: 内部用户手机号
* innerUserOfficeNumber: 内部用户办公电话
* innerUserBankAccount: 内部用户银行账户
* innerUserOrgId: 内部用户组织编号
* @return 请求map <位置-->Map<key,value>> 位置:header query body
* 如: {"body":{"token":"123"}}
*/
@Override
public Map<String, Object> doAuthentication(AuthenticationDto authenticationDto) throws Exception {
// 转换页面动态配置信息为dto
AuthDto authDto = JsonUtils.fromJson(authenticationDto.getJson(), AuthDto.class);
AuthenticationUserDto user = authenticationDto.getUser();
JsonDto jsonDto = new JsonDto();
String username = null;
if(user.getUserMap().get(authDto.getUsernameParam()) == null){
throw new BusinessException("安全登录:用户名为空");
}else {
username = user.getUserMap().get(authDto.getUsernameParam()).toString();
jsonDto.setXxx3(username);
}
if(user.getUserMap().get(authDto.getPasswordParam()) == null){
throw new BusinessException("安全登录:密码为空");
}else {
jsonDto.setXxx4( MD5Utils.md5(user.getUserMap().get(authDto.getPasswordParam()).toString()).toLowerCase(Locale.ROOT));
}
String json = JsonUtils.toJson(jsonDto);
String base64 = Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8));
log.info("安全登录,请求参数加密前:{}",json);
log.info("安全登录,请求参数加密后:{}",base64);
HttpResult httpResult = HttpClientUtil.sendPost(authDto.getTokenUrl(), base64);
if(httpResult.getStatusCode()!= 200){
throw new BusinessException("安全登录,请求返回结果码:{}", String.valueOf(httpResult.getStatusCode()));
}
log.info("安全登录,请求返回结果:{}",httpResult.getResult());
AuthTokenResponse authTokenResponse = JsonUtils.fromJson(httpResult.getResult(), AuthTokenResponse.class);
HashMap<String, Object> map = new HashMap<>();
map.put("user",username);
map.put("token", authTokenResponse.getToken());
if("param".equals(authDto.getParameterLocation())){
map.put("projectName",authDto.getProjectName());
}else{
map.put("project_name",authDto.getProjectName());
}
HashMap<String, Object> result = new HashMap<>();
result.put(authDto.getParameterLocation(),map);
return result;
}
5、注意事项
无
7 - 基础能力厂商通道
适用于COP平台已完成接入能力的通道扩展。如COP平台已接入短信服务,并已适配华为云通道、腾讯云通道。若系统使用中,需要使用阿里云或其他第三方通道,则可以通过SPI机制快速完成适配接
1. 概述
1.能力扩展SPI,适用于COP平台已完成接入能力的通道扩展。如COP平台已接入短信服务,并已适配华为云通道、腾讯云通道。若系统使用中,需要使用阿里云或其他第三方通道,则可以通过SPI机制快速完成适配接入。
2.因各能力厂商的版本、接口存在差异,可能无法满足某些API接口定义,则无法实现对应能力特征。当前已适配能力的特征及各通道区隔详情,请参看本页面的已接入能力列表。
2. 接入步骤
2.1. 开始开发
需要在代码工程POM文件中引入依赖
<dependency>
<groupId>com.seeyon</groupId>
<artifactId>cip-capability-api</artifactId>
<version>${capability.version}</version>
</dependency>
2.2. SPI适配层API接口定义实现
以“短信发送”API接口为例
需要实现接口:com.seeyon.cip.provider.api.sms.SmsProviderService
覆写以下方法:
com.seeyon.cip.provider.api.ProviderService#getDescription // 获取通道名称
com.seeyon.cip.provider.api.ProviderService#checkConfig // 检查配置开关,固定返回true
com.seeyon.cip.provider.api.ProviderService#getCapabilityEnum // 返回能力枚举
com.seeyon.cip.provider.api.sms.SmsProviderService#sendShortMessage // 实现短信发送逻辑
备注:服务的相关配置,可放在配置文件中。
3. 完成SPI加载配置
3.1. 工程下载
cip-spi-capability-demo.zip
注意事项:
1.pom中的版本号要与项目当前版本保持一致,分别为boot版本、cip-capability-api版本
<parent>
<groupId>com.seeyon</groupId>
<artifactId>boot</artifactId>
<version>3.10.1</version>
</parent>
<properties>
<platform.version>3.10.1</platform.version>
</properties>
<dependencies>
<dependency>
<groupId>com.seeyon</groupId>
<artifactId>cip-capability-api</artifactId>
<version>${cip.version}</version>
</dependency>
</dependencies>
3.2. spi jar 打包并部署
参考 SPI扩展
重启 cip-capability 项目实现扩展支持