这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

SPI扩展机制

1. 概述

当集成基础能力无法满足客户需求时,平台提供SPI扩展机制,用户可以在不影响上层使用的前提下,通过手写客开代码,实现统一身份认证、免登、单点登录、移动 App 接入、接口鉴权、基础能力厂商通道扩展等能力,解决个性化集成需求。

2. 能力架构

能力架构图

3. SPI 机制实现说明

3.1. spi jar 包项目开发并打包

下载帮助文档中对应功能 spi 示例的 demo 项目按需实现对应业务接口,并打包成 jar 包

  • spi 扩展 jar 包项目实现注意事项

img.png

  • 打包

1721907175054

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

注意:

  1. 两种配置根据项目情况取其一即可,jar包放到对应位置后,要确认jar包是否完整,对比下本地打的jar包大小,与服务器上的是否一致
  2. spi-plugins的值:- file:/data/xxx/xxx.jar, 短横杠 后面 1 个英文空格, 前面 6 个英文空格
  3. file:/data/xxx/xxx.jar 整体字符串中间 没有空格
  4. 所有缩进,以 两个英文空格 为标准, 不要使用 TAB 缩进
  5. 配置内容都是在 英文输入法 下配置,不要使用中文输入法
  6. 扩展 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'

1720668371813

5.2. 配置信息不对(配置格式层级不对)

举例如下

1720668395517

根据实际上传的版本来,比如此例中应该是

1720668448122

5.3. 配置中含有中文的空格,字符导致

字符-及后面的空格等全部要求是英文才可以,配置手写重新敲一遍配置

1720668462281

6、能力清单

1 - 统一身份认证

支持通过SPI扩展机制,接入三方统一身份认证系统。

1. 概述

使用三方认证中心进行统一身份认证, 在登录 v8 系统时, 会先跳转到三方认证中心进行登录, 三方认证中心登录成功后, 重定向 v8 目标地址,完成系统登录过程。

img.png

img.png

img.png

2. spi 接入导图

统一身份认证时序图

1721720315930

1721720315930

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. 异常跟踪

1721904733313

3.6. 内容校验

浏览器地址输入:<domain>/service/ctp-user/api/sso-config

1722921841278

1722921854925

确认内容

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. 用户登录报错时,跳转到自定义错误页

说明:免登失败时,自动跳转到自定义错误页,支持自定义错误信息可视

1721627287151

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

1720767916820

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

1722921937706

通过免登地址,登录 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

1720767916820

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、概述

单点登录场景:

  1. 点击V8菜单跳转三方系统。
  2. 点击三方栏目更多跳转三方系统。
  3. 点击通过集成应用同步过来的三方系统待办、消息,跳转至三方系统。

2、接入导图

1721721091281

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、效果实例:

1724307195093

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工作台中,例如企业微信、钉钉、飞书等。

mobile1
2.点击工作台应用图标免登进入V8应用。 3.V8产生的消息推送至三方APP。 4.V8组织人员信息同步至三方APP(可选)。

2、接入导图

mobile2

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.必要条件,修改自定义类型

mobile5

5、注意事项

mobile3

mobile4


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 项目实现扩展支持