# 与SuccezBI3.x单点登录

本文讲述 SuccBI4.x及后续版本(下文用本系统指代) 如何与SuccezBI3.x(下文用3.x指代)共享用户库以及单点登录:

# 使用3.x的用户库

由于本系统和3.x所使用的用户表结构存在差异,需要将3.x的用户数据同步到本系统内置用户表中(可以通过数据加工进行提取)

需要注意的是 3.x 直接使用 MD5 对密码进行加密,本系统在给密码加盐后再对密码使用 sha1 进行加密,由于MD5 是非对称加密,无法解析出用户的明文密码,同步数据时应该忽略掉密码,

由于可能3.x环境中新增了用户,没有及时同步到本系统中的问题,用户在本系统中登录过程为: 根据登录用户账号与密码向3.x用户库中查找用户信息,并校验密码登录密码是否正确,校验成功后,检查本系统内置用户库中是否存在该用户,不存在则向本系统用户库中添加一个用户

考虑到登录流程与使用本系统内置登录流程不一样,需要使用登录脚本功能做到这一点:

脚本模板如下:

"use strict";

var db = require("svr-api/db");
var utils = require("svr-api/utils");
/**
 * 当一个用户使用用户名密码方式登录时校验账号密码时候调用。
 *
 * 注意:
 * 	1. 当执行此回调函数时,用户还未登录成功,系统会根据此函数返回的结果决定后续的操作
 * 	2. 账号为 admin 的用户登录时不受这个脚本函数的影响
 * 
 * @param request
 * @param response 这个属性不再使用
 * @param userId 用户输入的用户ID或者手机号
 * @param password 明文密码
 * @param userDirectory 用户目录。用于标识用户的来源,系统内置的区分有:`sys`表示系统用户,`external`表示外部用户
 * @returns
 * 	1. 如果明确返回`UserInfo`对象,那么将绕过系统默认的登录验证逻辑,直接使用返回的用户信息登录。  
 * 	2. 如果抛出异常,那么将导致用户登录失败,异常信息会显示给用户,可用于进行额外的登录验证判断。  
 * 	3. 如果没有返回值,那么将进行系统默认的登录校验 
 */
function verifyLoginPassword(request, userId, password, userDirectory) {
    var ds = db.getDataSource("${datasourceName}"); //获取与3.x用户库的连接, datasourceName 为本系统数据源中对3.x用户库的数据源名称,使用的时候请替换为正确内容
    var sqlResult = ds.executeQuery("select * from szsys_1_metauser where USERID = ?", [userId]); // 如果用户表被替换,请将表名替换为正确的内容
    if(!sqlResult.length){
        throw new Error("用户不存在或不可用");
    }
    var user = sqlResult[0];
    if (!user || !user.ENABLED) {
        throw new Error("用户不存在或不可用");
    }

    if (user.PASSWORD !== utils.md5(password +'\t'+  user.SALT + "\t")) {
        throw new Error("密码不正确");
    }
    var defaultDs = db.getDefaultDataSource(); // 本系统默认数据连接,存储了内置的用户表
    var userTableData = defaultDs.openTableData("SZSYS_4_USERS");
    sqlResult=  userTableData.executeQuery("select * from SZSYS_4_USERS WHERE USER_ID = ?", [userId]);
    var ret;
    if (!sqlResult.length) {
        userTableData.insert({ USER_ID: userId, USER_NAME: user.USERNAME, ENABLED: 1, EMAIL: user.EMAIL, PHONE: user.MB, SALT: utils.randomString(), PASSWORD: utils.uuid() });
        ret = {
            userId: userId,
            userName: user.USERNAME,
            email: user.EMAIL,
            enabled: true,
            phone: user.MB
        };
    } else {
        var user4 =  sqlResult[0];
        ret = {
            userId: userId,
            userName: user4.USER_NAME,
            email: user4.EMAIL,
            enabled: true,
            phone: user4.PHNOE
        };
    }
    return ret;
}

注意:

  1. 这个登录脚本的使用前提是在本系统中配置了包含 3.x 用户库的数据源
  2. 需要替换其中 var ds = db.getDataSource("${datasourceName}") 中的datasourceName 为本系统中所配置 3.x 用户库数据源名称
  3. 若3_x 用户表也被替换,var sqlResult = ds.executeQuery("select * from szsys_1_dimuser where USERID = ?", [userId]); 这一行中所执行的sql 所查询的表也需要改变

# 将3.x系统页面嵌入到本系统中

这里与将本系统嵌入第三方系统采用一样的方案,只是相对于第三方应用,3.x系统已经内置了:

  • 验证认证信息然后自动登录的接口。
  • 配置本系统的系统证书为信任证书界面。

通过本系统访问3.x系统流程如下:

流程图

在完成如下配置后,即可在已经登录本系统的情况下从本系统跳转免登录访问到3.x系统:

  1. 在本系统中生成系统证书

  2. 在 3.x 环境中配置本系统的系统证书,信任证书配置地址为 系统设置 > 安全 > 证书管理 > 信任证书

    3.x 信任证书

  3. 如果本系统与3.x系统不是部署在同一个域名中并且需要使用iframe来展示3.x系统页面,则还需要针对3.x系统处理跨域问题

PS:本系统配置与3.x 信任证书的配置参数名对应为:

本系统参数 3.x证书参数
系统ID 名称
系统名称 标题
证书 证书

将本系统嵌入第三方系统页面示例参照:示例地址

# 将本系统链接嵌入到3.x系统中

这里与本系统中嵌入第三方应用链接采用一样的方案,相对于第三方应用,3.x系统已经内置了:

通过3.x系统访问本系统流程如下:

流程图

在完成如下配置后,即可在已经登录3.x系统的情况下从3.x系统跳转免登录访问到本系统:

  1. 在3.x系统生成证书,查看地址为 系统管理 > 安全 > 证书管理 > 系统证书

    3.x 系统证书

  2. 将3.x系统的系统证书配置作为注册为本系统证书授信应用

  3. 如果本系统与3.x系统不是部署在同一个域名中并且需要使用iframe来展示本系统的页面,则还需要针对本系统处理跨域问题

注意:

  • 本系统证书授信应用配置与3.x 系统证书的配置参数名对应为:

    本系统参数 3.x证书参数
    应用ID 名称
    应用名称 标题
    证书 证书
  • 请将3.x系统证书中生成的证书选项复制到本系统的证书授信应用对应的证书中:因为3.x系统没有提供自定义系统证书私钥的方式。

下面以3.x系统报表中插入iframe (opens new window)访问本系统为例:

iframe

iframe

是否有帮助?
0条评论
评论