# 与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;
}
注意:
- 这个登录脚本的使用前提是在本系统中配置了包含 3.x 用户库的数据源
- 需要替换其中
var ds = db.getDataSource("${datasourceName}")
中的datasourceName 为本系统中所配置 3.x 用户库数据源名称 - 若3_x 用户表也被替换,
var sqlResult = ds.executeQuery("select * from szsys_1_dimuser where USERID = ?", [userId]);
这一行中所执行的sql 所查询的表也需要改变
# 将3.x系统页面嵌入到本系统中
这里与将本系统嵌入第三方系统采用一样的方案,只是相对于第三方应用,3.x系统已经内置了:
- 验证认证信息然后自动登录的接口。
- 配置本系统的系统证书为信任证书界面。
通过本系统访问3.x系统流程如下:
在完成如下配置后,即可在已经登录本系统的情况下从本系统跳转免登录访问到3.x系统:
在本系统中生成系统证书。
在 3.x 环境中配置本系统的系统证书,信任证书配置地址为 系统设置 > 安全 > 证书管理 > 信任证书:
如果本系统与3.x系统不是部署在同一个域名中并且需要使用iframe来展示3.x系统页面,则还需要针对3.x系统处理跨域问题。
PS:本系统配置与3.x 信任证书的配置参数名对应为:
本系统参数 | 3.x证书参数 |
---|---|
系统ID | 名称 |
系统名称 | 标题 |
证书 | 证书 |
将本系统嵌入第三方系统页面示例参照:示例地址。
# 将本系统链接嵌入到3.x系统中
这里与本系统中嵌入第三方应用链接采用一样的方案,相对于第三方应用,3.x系统已经内置了:
- 系统证书的生成 (opens new window)。
- 使用证书私钥加密生成认证信息的接口。
通过3.x系统访问本系统流程如下:
在完成如下配置后,即可在已经登录3.x系统的情况下从3.x系统跳转免登录访问到本系统:
在3.x系统生成证书,查看地址为 系统管理 > 安全 > 证书管理 > 系统证书
将3.x系统的系统证书配置作为注册为本系统证书授信应用
如果本系统与3.x系统不是部署在同一个域名中并且需要使用iframe来展示本系统的页面,则还需要针对本系统处理跨域问题。
注意:
本系统证书授信应用配置与3.x 系统证书的配置参数名对应为:
本系统参数 3.x证书参数 应用ID 名称 应用名称 标题 证书 证书 请将3.x系统证书中生成的
证书
选项复制到本系统的证书授信应用对应的证书
中:因为3.x系统没有提供自定义系统证书私钥的方式。
下面以3.x系统报表中插入iframe (opens new window)访问本系统为例: