Smartbi 与第三方系统相互集成过程中,通常需要由第三方系统接管某些 Smartbi 的功能,比如用户的登录验证需要由第三方统一认证平台完成、需要将 Smartbi 的资源同步到第三方系统、由第三方系统进行资源权限以及操作权限的验证等。上述需求,将通过如下方法实现。
第三方系统接管 Smartbi 的功能,实现方式是相同的,都是由第三方系统开发相关 Java 类实现 Smartbi 指定的接口,然后在 Smartbi 中进行配置使用该 Java 类。Smartbi 会在相关的扩展点处调用第三方 Java 类,从而达到让第三方系统接管相关功能的目的。对于每一种功能接管,具体操作步骤如下。
如果在项目中使用第三方系统的权限验证,很可能也需要同步 Smartbi 资源树信息到第三方系统中以配合权限验证,即每当Smartbi中的资源树发生变化就通知第三方系统及时更新。
1、在扩展包中新建一个Java类com.func.takeover.catalogtree.TreeSyncDemo,并且实现接口smartbi.catalogtree.ICatalogTreeListener。
2、配置新建的Java类,方式有如下两种:
(1)在扩展包中新建Module类,具体请参考wiki文档:自定义Module 或者参考下面的示例扩展包。在Module类的active方法中使用该段代码((CatalogTreeModule)catalogTreeModule).addCatalogTreeListener(new TreeSyncDemo());配置。
(2)编辑 Smartbi 服务器配置文件smartbi-config.xml,如下图红色框所示。在已有节点catalogtree下面新增子节点catalog-tree-listener,其属性为TreeSyncDemo类的全名com.func.takeover.catalogtree.TreeSyncDemo。
3、gif演示示例的源码请参考:资源树同步.rar
如果在项目中要统一管理操作日志,有可能需要将 Smartbi 的操作日志按指定的形式输出到指定的地方。
1、在扩展包中新建一个Java类com.log.takeover.log.LogSyncDemo,并且实现接口 smartbi.repository.IOperationLogReceiver。
2、编辑Smartbi服务器配置文件smartbi-config.xml,如下图红色框所示。在已有节点smartbi下面新增子节点operationlog,接着在节点operationlog下新增子节点preserver-class,其属性值为 LogSyncDemo 类的全名 com.log.takeover.log.LogSyncDemo。
3、gif演示示例的源码请参考:操作日志重定向.rar
第三方系统的用户管理能够包含 Smartbi 用户管理中的所有语义(用户组、角色、用户及其相应关系等),并且资源权限也希望由第三方系统统一管理,则可以屏蔽 Smartbi 的用户管理模块而使用第三方系统的用户管理作为统一用户管理平台。以下将介绍如何在外部系统中调用 Smartbi 用户管理模块。
详情请参考wiki:用户管理 目录下的用户管理章节和权限管理章节。
用户属性继承有三种方式,第一种是在使用iframe集成Smartbi的用户管理模块,直接在iframe中管理用户属性,第二种是直接操作用户属性对应的数据库表,第三种是通过服务器端SDK API管理用户属性。
1、在集成的用户管理模块中增加用户扩展属性
根据以上步骤使用iframe在第三方系统中集成了用户管理模块后,可以在第三方系统中增加用户扩展属性,具体步骤如下:
(1)在系统运维 > 系统选项 > 用户管理设置 > 用户扩展属性 > 设置中
(2)添加用户扩展属性
(3)清空缓存,重新进入用户管理,对任意一个用户进行设置,就可以看到刚刚添加的用户扩展属性
2、直接通过知识库以对用户扩展属性进行修改
用户扩展属性,定义在知识库的 t_systemconfig 表中,在其中 c_key 为 USER_EXTEND_SETTING 的行中,通过 c_long 列,以JSON形式定义。
可通过下面的语句查询到该行数据:
SELECT * FROM t_systemconfig where c_key = "USER_EXTEND_SETTING"; |
如配置了前面的用户扩展属性后,查询结果可能为:
修改 c_long 下的JSON即可对用户扩展属性进行修改。
3、通过服务器端SDK API对用户扩展属性进行读取
(1)读取用户扩展属性结构
通过 smartbi.sdk.service.systemconfig.SystemConfigService 可以对用户扩展属性的结构进行读取:
ClientConnector conn = new ClientConnector("http://localhost:18080/smartbi"); conn.open("admin", "manager"); SystemConfigService service = new SystemConfigService(conn); SystemConfig config = service.getSystemConfig("USER_EXTEND_SETTING"); System.out.println(config); conn.close(); |
结果形如:
key=USER_EXTEND_SETTING;value=;longValue=[{"name":"用户扩展属性1","alias":"","typeS":"文本框","valueLength":"100"}] |
(2)修改、读取用户属性值
通过 smartbi.sdk.service.user.UserManagerService 可以对用户属性值进行读取、修改:
ClientConnector conn = new ClientConnector("http://localhost:18080/smartbi"); conn.open("admin", "admin"); UserManagerService service = new UserManagerService(conn); service.updateUserAttribute("ADMIN", "用户扩展属性1", "ExampleValue", ""); // 修改用户属性 IExtensionAttribute attr = service.getUserAttribute("ADMIN", "用户扩展属性1"); // 读取用户属性 System.out.println(attr.getValue()); conn.close(); |
实际项目中往往存在多个系统需要统一登录认证,客户要求将某个系统作为统一登录认证平台,其余系统访问此系统来进行登录认证。这种情况下,不需要再使用 Smartbi 产品的用户管理模块来管理组和用户,但还需要保留通过角色来设置操作权限。Smartbi 用户管理模块为了应对这种需求,提供了一个可以根据需要扩充的用户验证方式,让项目能根据实际情况开发不同的需求。具体实现请参考:使用第三方系统的用户验证。
实际项目中往往存在多个系统需要统一权限认证,客户要求将某个系统作为统一认证平台, Smartbi 为了应对这种需求,提供了一个可以根据需要扩充的资源权限验证方式,让项目能根据实际情况开发不同的需求。具体实现请参考:使用第三方系统的资源权限验证。
不使用 Smartbi 系统自身的操作权限验证逻辑,而是由第三方系统进行操作权限验证,给 Smartbi 返回一个用户能否访问指定操作的状态指示。
1. 在扩展包中新建一个Java类 com.mycomp.usermanager.TestFunctionAuth,并且实现接口 smartbi.usermanager.IFunctionAuth。
package com.mycomp.usermanager; public class TestFunctionAuth implements IFunctionAuth { private static TestFunctionAuth auth = new TestFunctionAuth(); public static TestFunctionAuth getInstance() { return auth; } private TestFunctionAuth() { // TestFunctionAuth } public boolean isFuncTypeAccessible(String userId, String functionCode) { // 在这里实现用户操作权限判断的逻辑,返回状态 true|false 指明用户能否访问指定操作 return true; } } |
2. 修改扩展包文件 applicationContext.xml 增加如下内容。
<bean id="usermanager" class="smartbi.usermanager.UserManagerModule" factory-method="getInstance"> <property name="functionAuth" ref="TestFunctionAuth"/> </bean> <bean id="TestFunctionAuth" class="com.mycomp.usermanager.TestFunctionAuth" factory-method="getInstance"></bean> |