工作流引擎Flowable是从Activiti引擎Fork出来的一个版本,它更加友好,且与Activiti完全兼容,值得推荐(事实上是因为访问flowable.org比访问activiti.org要快一些)。本文讨论的方案均可用于Activiti引擎。
因为Flowable有自己的一套用户权限体系,但是我们的业务系统都会提供更完善的用户权限,所以,整合这两套用户就是一个我们在实践中必须要解决的问题。官方提供的方案无外乎三个:一是同步用户数据;二是扩展代码,实现自己的UserEntityManager等;三是用视图取代原来的几个表。很显然,方案三是最简单的,完全不需要写代码。
本文讨论的就是方案三。Flowable提供的权限体系比较简单:用户User-组Group,但我们的业务系统却是:用户User-部门Group-角色Role。比如,我们会有『组织部秘书』或『组织部部长』这样的区分,而原来的Flowable则只有简单的『管理员』或『用户』,我们需要做的事情就是如何将『部门-角色』映射到『Group』。
下面我们就切入正题,说说如何具体实现用户视图取代表来解决两个系统的统一用户认证。
首先,我们先将Flowable中的三张表改名:
原表名 | 新表名 |
---|---|
ACT_ID_USER | XXX_ACT_ID_USER |
ACT_ID_GROUP | XXX_ACT_ID_GROUP |
ACT_ID_MEMBERSHIP | XXX_ACT_ID_MEMBERSHIP |
我们有这样的几张业务表需要映射到Flowable中,下面分述之。
用户表(t_user)
字段名 | 说明 |
---|---|
id | 用户ID |
login_name | 登录名(账号) |
real_name | 真实姓名(显示名称) |
邮箱 | |
avatar_url | 头像ID |
有一个密码字段,因为我们的业务表中加密保存而在Flowable中却是明文,所以,需要特殊处理,所以这里不需要考虑,直接用000000来做密码。我们将它映射到Flowable中的用户表,可以创建一个视图,命名为ACT_ID_USER,语句下所示(为方便起见仅给出select子句)。
select
t1.login_name as ID_,
t1.login_type as REV_,
t1.real_name as FIRST_,
concat('',t1.id) as LAST_,
t1.email as EMAIL_,
'000000' as PWD_,
t1.avatar_url as PICTURE_ID_
from oa_system.t_user t1
union
select ID_,REV_,FIRST_,LAST_,EMAIL_,PWD_,PICTURE_ID_
from XXXX_ACT_ID_USER
这里我们将前面改名为xxx_act_id_user的表也通过union包进来,可以包含原来的那些DEMO用户,如果不需要,可以省略这个union。
部门表(t_group)
字段名 | 说明 |
---|---|
id | 部门ID |
pid | 上级部门ID |
group_name | 部门名称 |
group_master_id | 部门分管校领导ID |
这里的group_master_id用于记录该部门的分管校领导,是除部门领导之外的另一个会影响到用户权限的字段。
角色表(t_role)
字段名 | 说明 |
---|---|
id | 角色ID |
role_code | 角色代码 |
role_name | 角色名称(用于显示) |
然后,我们需要将这两张表进行合并,以映射到Flowable的Group中,所以可以这样做:
select
concat(t1.id,':',t2.role_code) as ID_,
1 as REV_,
concat(t1.group_name,':',t2.role_name) as NAME_,
case when t1.id=1 and t2.role_code='system' then 'security-role'
else 'assignment' end as TYPE_
from oa_system.t_group t1,oa_system.t_role t2
union
select ID_,REV_,NAME_,TYPE_
from XXXX_ACT_ID_GROUP
我们用冒号作为组ID与角色的分隔符,比如 4:security 表示ID为4的部门的秘书角色,并且将它作为Flowable中的Group的ID,同时,需要考虑我们业务表中有一个角色叫system,是系统管理员,所以将它也作为Flowable中的管理员。
如此一来,我们会得到一张大表(视图),N个部门*M个角色的记录数。
关系表(t_group_role_user)
字段名 | 说明 |
---|---|
group_id | 部门ID |
role_id | 角色ID |
user_id | 用户ID |
很明显,我们的用户是可以在不同部门扮演不同的角色。同样,我们也将它映射到Flowable中去。
select
t3.login_name as USER_ID_,
concat(t1.group_id,':',t2.role_code) as GROUP_ID_
from oa_system.t_group_role_user t1
left join oa_system.t_role t2 on t1.role_id=t2.id
left join oa_system.t_user t3 on t3.id=t1.user_id
union
select
t2.login_name as USER_ID_,
concat(t1.id,':president') as GROUP_ID_
from oa_system.t_group t1 left join oa_system.t_user t2 on t1.group_master_id=t2.id
where t1.group_master_id is not null
union
select USER_ID_,GROUP_ID_ from XXXX_ACT_ID_MEMBERSHIP
这里我们union了三个查询子句,其中第二个就是用来处理部门的分管校领导这个概念。因为部门正常的领导是manager,所以,如果用户被分配到该部门的president,就是将他作为分管领导配置的。
至此,我们用视图实现了三张表USER,GROUP,MEMBERSHIP,现在可以使用业务系统中的用户正常访问Flowable了。
比如,我们可以这样动态配置candidateGroups=”12:security”。