Flowable-自定义权限

需求

在实际项目使用flowable时,一般公司都有自己的人员权限系统,并不会直接使用flowable的idm模块,本节内容记录,如何让flowable调用自己的权限系统

idm基本操作

核心类:IdentityService

通过该类可以获取,在流程的整个生命周期中的相关人,和组信息

例如:

获取可提交流程的人:

1
List<User> authorizedUsers = identityService.getPotentialStarterUsers(processDefId);

获取组内的人:

1
List<User> userList = identityService.createUserQuery().memberOfGroups(groupIds).list();

两个核心的方法,createUserQuery()和createUserQuery(),用来构建获取人和组的方法

实现类IdmIdentityServiceImpl

上面人员权限认证服务的默认实现类

1
public class IdmIdentityServiceImpl extends CommonEngineServiceImpl<IdmEngineConfiguration> implements IdmIdentityService

查看两个核心方法createUserQuery()和createUserQuery()

如果自定义idm,需要实现UserQuery,和 GroupQuery两个接口

官方默认的实现类是UserQueryImpl,和GroupQueryImpl

为了实现简单,只需要修改自定义业务用的方法,所以我们可以直接继承这两个类就可以

代码改造

实现UserQuery

主要重写executeList方法。

该方法是查询数据的核心方法,在这个方法里,写自定义获取用户的代码就可以了

getId()获取当前查询里的用户id。

getIds()获取当前查询里的用户id列表。

getGroupId()获取当前查询里的组id。

getGroupIds()获取当前查询里的组id列表,

为什么要用这些数据做判断,是因为在构建查询的时候,代码里编写了创建查询的指令,如果存在指令,对应的get方法里就会有我们传入的值,例如:

获取组内的人:identityService.createUserQuery().memberOfGroups(groupIds).list();

.memberOfGroups(groupIds)这个指令就会使getGroupIds()时获取到传入的groupIds。

具体实例代码实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/**
* 集成自己的用户实现方式
* @author iseven.yang
* @date 2021/11/1 10:18
*/
@Slf4j
public class MyUserQueryImpl extends UserQueryImpl {

@Override
public long executeCount(CommandContext commandContext) {
return executeList(commandContext).size();
}

@Override
public List<User> executeList(CommandContext commandContext) {
log.info("开始获取人员信息***********************************");
if(getId() != null) {
List<User> users = new ArrayList<>();
users.add(findById(getId()));
return users;
} else if(getIds() != null) {
return findByIds(getIds());
} else if(getGroupId() != null) {
return findByGroup(getGroupId());
} else if(getGroupIds() != null) {
return findByGroups(getGroupIds());
}
return null;
}

private static Map<String, List<Long>> SHIP = new HashMap<>();
static {
SHIP.put("aaa", Arrays.asList( 9L));
SHIP.put("bbb", Arrays.asList(10L, 11L, 12L));
SHIP.put("ccc", Arrays.asList(11L));
SHIP.put("ddd", Arrays.asList(13L));
SHIP.put("eee", Arrays.asList(14L));
}

public QtUser getQtUser(String userId) {
if(USERS.containsKey(Long.valueOf(userId))) {
QtUser user = new QtUser();
user.setId(Long.valueOf(userId));
user.setName(USERS.get(Long.valueOf(userId)));
user.setTenantId(1L);
return user;
}
return null;
}

private static Map<Long, String> USERS = new HashMap<>();
static {
USERS.put(8L, "ie");
USERS.put(9L, "he");
USERS.put(10L, "tom");
USERS.put(11L, "cat");
USERS.put(12L, "java");
USERS.put(13L, "python");
USERS.put(111L, "li");
USERS.put(222L, "qa");
}

private User findById(final String userId) {
if(!USERS.containsKey(Long.valueOf(userId))) {
return null;
}
UserEntity userEntity = new UserEntityImpl();
userEntity.setId(userId);
userEntity.setDisplayName(USERS.get(Long.valueOf(userId)));
userEntity.setTenantId("1");
return userEntity;
}

private List<User> findByIds(List<String> userIds) {
return userIds.stream().map(this::findById).collect(Collectors.toList());
}

private List<User> findByGroup(final String groupId) {
List<Long> userIds = SHIP.get(groupId);
if(CollUtil.isNotEmpty(userIds)) {
return findByIds(userIds.stream().map(String::valueOf).collect(Collectors.toList()));
}
return null;
}

private List<User> findByGroups(List<String> groupIds) {
List<User> users = new ArrayList<>();
groupIds.forEach(g -> users.addAll(findByGroup(g)));
return users;
}
}

实现GroupQuery

和上面一样,也是主要实现executeList方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* @author iseven.yang
* @date 2021/11/1 10:18
*/
@Slf4j
public class MyGroupQueryImpl extends GroupQueryImpl {

@Override
public long executeCount(CommandContext commandContext) {
return executeList(commandContext).size();
}

@Override
public List<Group> executeList(CommandContext commandContext) {
log.info("开始获取组信息***********************************");
if (getUserId() != null) {
return findGroupsByUser(getUserId());
} else if (getId() != null) {
List<Group> groups = new ArrayList<>();
groups.add(findGroupById(getId()));
return groups;
} else if (getIds() != null) {
return findGroupsByIds(getIds());
}
return null;
}

private static Map<Long, List<String>> SHIP = new HashMap<>();
static {
SHIP.put(8L, Arrays.asList("aaa"));
SHIP.put(9L, Arrays.asList("aaa"));
SHIP.put(10L, Arrays.asList("bbb"));
SHIP.put(11L, Arrays.asList("bbb","ccc"));
SHIP.put(12L, Arrays.asList("bbb"));
SHIP.put(13L, Arrays.asList("ddd"));
SHIP.put(14L, Arrays.asList("eee"));
}

private static Map<String, String> GROUPS = new HashMap<>();
static {
GROUPS.put("aaa", "权限1");
GROUPS.put("bbb", "权限2");
GROUPS.put("ccc", "权限3");
GROUPS.put("ddd", "权限4");
GROUPS.put("eee", "权限5");
}

private List<Group> findGroupsByUser(String userId) {
List<String> strings = SHIP.get(Long.valueOf(userId));
return strings.stream().map(g -> {
Group group = new GroupEntityImpl();
group.setId(g);
group.setName(GROUPS.get(g));
return group;
}).collect(Collectors.toList());
}

private Group findGroupById(String id) {
if(!GROUPS.containsKey(id)) {
return null;
}
Group group = new GroupEntityImpl();
group.setId(id);
group.setName(GROUPS.get(id));
return group;
}

private List<Group> findGroupsByIds(List<String> ids) {
return ids.stream().map(this::findGroupById).collect(Collectors.toList());
}
}

重写IdmIdentityServiceImpl

IdmIdentityServiceImpl为构建查询的默认实现类,需要重写一个类,使idm调用自定义的MyUserQueryImpl和MyGroupQueryImpl

1
2
3
4
5
6
7
8
9
10
11
12
public class MyIdmIdentityServiceImpl extends IdmIdentityServiceImpl {

@Override
public UserQuery createUserQuery() {
return new MyUserQueryImpl();
}

@Override
public GroupQuery createGroupQuery() {
return new MyGroupQueryImpl();
}
}

使flowable加载自定义实现的Idm

在配置类里加入bean

1
2
3
4
@Bean
public EngineConfigurationConfigurer<SpringIdmEngineConfiguration> idmEngineConfigurationConfigurer() {
return idmEngineConfiguration -> idmEngineConfiguration.setIdmIdentityService(new MyIdmIdentityServiceImpl());
}

至此,自定义idm模块改造完成,重启服务,测试一下