LDAP 集成
企业通常已经以 LDAP 系统的形式拥有用户和组存储。Flowable 提供了开箱即用的解决方案,可以轻松配置 Flowable 如何连接 LDAP 系统。
在早期版本中,已经可以集成 LDAP,但此后配置方式已大大简化。不过,"旧的" LDAP 配置方式仍然有效。更具体地说,简化配置只是在"旧"基础设施之上的一层封装。
用法
要将 LDAP 集成代码添加到你的项目中,只需在 pom.xml 中添加以下依赖:
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ldap-configurator</artifactId>
<version>latest.version</version>
</dependency>
用例
LDAP 集成目前主要有两个用例:
- 通过 IdentityService 进行认证。当所有操作都通过 IdentityService 完成时,这会很有用。
- 获取用户的组。例如在查询任务、查看某个用户能看到哪些任务(即具有候选组的任务)时,这一点很重要。
配置
将 LDAP 系统与 Flowable 集成,是通过在流程引擎配置的 idmProcessEngineConfigurator 部分注入一个 org.flowable.ldap.LDAPConfigurator 实例来完成的。该类高度可扩展:可以轻松覆盖其方法;如果默认实现不适用,许多依赖的 bean 都是可插拔的。
下面是一个配置示例(注意:以编程方式创建引擎时,配置完全类似)。现在先不必关心所有属性,我们将在下一节详细讲解它们。
<bean id="processEngineConfiguration" class="...SomeProcessEngineConfigurationClass">
...
<property name="idmProcessEngineConfigurator">
<bean class="org.flowable.ldap.LDAPConfigurator">
<property name="ldapConfiguration">
<bean class="org.flowable.ldap.LDAPConfiguration">
<!-- Server connection params -->
<property name="server" value="ldap://localhost" />
<property name="port" value="33389" />
<property name="user" value="uid=admin, ou=users, o=flowable" />
<property name="password" value="pass" />
<!-- Query params -->
<property name="baseDn" value="o=flowable" />
<property name="queryUserByUserId" value="(&(objectClass=inetOrgPerson)(uid={0}))" />
<property name="queryUserByFullNameLike" value="(&(objectClass=inetOrgPerson)(|({0}=*{1}*)({2}=*{3}*)))" />
<property name="queryAllUsers" value="(objectClass=inetOrgPerson)" />
<property name="queryGroupsForUser" value="(&(objectClass=groupOfUniqueNames)(uniqueMember={0}))" />
<property name="queryAllGroups" value="(objectClass=groupOfUniqueNames)" />
<!-- Attribute config -->
<property name="userIdAttribute" value="uid" />
<property name="userFirstNameAttribute" value="cn" />
<property name="userLastNameAttribute" value="sn" />
<property name="userEmailAttribute" value="mail" />
<property name="groupIdAttribute" value="cn" />
<property name="groupNameAttribute" value="cn" />
</bean>
</property>
</bean>
</property>
</bean>
属性
可以在 org.flowable.ldap.LDAPConfiguration 上设置以下属性:
.LDAP configuration properties
| 属性名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| server | 可访问 LDAP 系统的服务器。例如 'ldap://localhost:33389' | String | |
| port | LDAP 系统运行的端口 | int | |
| user | 用于连接 LDAP 系统的用户 id | String | |
| password | 用于连接 LDAP 系统的密码 | String | |
| initialContextFactory | 用于连接 LDAP 系统的 InitialContextFactory 名称 | String | com.sun.jndi.ldap.LdapCtxFactory |
| securityAuthentication | 用于连接 LDAP 系统的 'java.naming.security.authentication' 属性的值 | String | simple |
| customConnectionParameters | 允许设置所有没有专用 setter 的 LDAP 连接参数。自定义属性示例参见 http://docs.oracle.com/javase/tutorial/jndi/ldap/jndi.html。例如配置连接池、特定安全设置等。所提供的所有参数都将在建立到 LDAP 系统的连接时使用。 | Map<String, String> | |
| baseDn | 搜索用户和组时作为起点的基础 'distinguished name'(DN) | String | |
| userBaseDn | 搜索用户时作为起点的基础 'distinguished name'(DN)。如果未提供,将使用 baseDn(见上) | String | |
| groupBaseDn | 搜索组时作为起点的基础 'distinguished name'(DN)。如果未提供,将使用 baseDn(见上) | String | |
| searchTimeLimit | 在 LDAP 中执行搜索时使用的超时时间,单位为毫秒 | long | one hour |
| queryUserByUserId | 按 userId 搜索用户时执行的查询。例如:(&(objectClass=inetOrgPerson)(uid={0})) 此时将返回 LDAP 中所有类别为 'inetOrgPerson' 且 'uid' 属性值匹配的对象。如示例所示,用户 id 通过 {0} 注入。如果仅设置查询不足以满足你的特定 LDAP 配置,可以换用不同的 LDAPQueryBuilder,从而获得比仅设置查询更多的定制能力。 | string | |
| queryUserByFullNameLike | 按全名搜索用户时执行的查询。例如:(&(objectClass=inetOrgPerson)( | ({0}={1})({2}={3}))) 此时将返回 LDAP 中所有类别为 'inetOrgPerson' 且名字和姓氏值匹配的对象。请注意,{0} 注入的是 firstNameAttribute(如上定义),{1} 和 {3} 为搜索文本,{2} 为 lastNameAttribute。如果仅设置查询不足以满足你的特定 LDAP 配置,可以换用不同的 LDAPQueryBuilder,从而获得比仅设置查询更多的定制能力。 | string |
| queryAllUsers | 不带过滤器搜索用户时执行的查询。例如:(objectClass=inetOrgPerson) 此时将返回 LDAP 中所有类别为 'inetOrgPerson' 的对象。 | string | |
| queryGroupsForUser | 搜索特定用户的组时执行的查询。例如:(&(objectClass=groupOfUniqueNames)(uniqueMember={0})) 此时将返回 LDAP 中所有类别为 'groupOfUniqueNames' 且所提供 DN(与某个用户的 DN 匹配)是其 'uniqueMember' 的对象。如示例所示,用户 id 通过 {0} 注入。如果仅设置查询不足以满足你的特定 LDAP 配置,可以换用不同的 LDAPQueryBuilder,从而获得比仅设置查询更多的定制能力。 | string | |
| queryAllGroups | 不带过滤器搜索组时执行的查询。例如:(objectClass=groupOfUniqueNames) 此时将返回 LDAP 中所有类别为 'groupOfUniqueNames' 的对象。 | string | |
| userIdAttribute | 与用户 id 匹配的属性名。该属性用于查找 User 对象,以及完成 LDAP 对象与 Flowable User 对象之间的映射。 | string | |
| userFirstNameAttribute | 与用户名字匹配的属性名。该属性用于查找 User 对象,以及完成 LDAP 对象与 Flowable User 对象之间的映射。 | string | |
| userLastNameAttribute | 与用户姓氏匹配的属性名。该属性用于查找 User 对象,以及完成 LDAP 对象与 Flowable User 对象之间的映射。 | string | |
| groupIdAttribute | 与组 id 匹配的属性名。该属性用于查找 Group 对象,以及完成 LDAP 对象与 Flowable Group 对象之间的映射。 | string | |
| groupNameAttribute | 与组名匹配的属性名。该属性用于查找 Group 对象,以及完成 LDAP 对象与 Flowable Group 对象之间的映射。 | String | |
| groupTypeAttribute | 与组类型匹配的属性名。该属性用于查找 Group 对象,以及完成 LDAP 对象与 Flowable Group 对象之间的映射。 | String |
以下属性用于自定义默认行为或与引入的组缓存相关:
高级属性
| 属性名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| ldapUserManagerFactory | 如果默认实现不合适,可以设置 LDAPUserManagerFactory 的自定义实现。 | LDAPUserManagerFactory 的实例 | |
| ldapGroupManagerFactory | 如果默认实现不合适,可以设置 LDAPGroupManagerFactory 的自定义实现。 | LDAPGroupManagerFactory 的实例 | |
| ldapMemberShipManagerFactory | 如果默认实现 不合适,可以设置 LDAPMembershipManagerFactory 的自定义实现。请注意这不太可能用到,因为成员关系通常由 LDAP 系统自身管理。 | LDAPMembershipManagerFactory 的实例 | |
| ldapQueryBuilder | 如果默认实现不合适,可以设置自定义查询构建器。LDAPQueryBuilder 实例用于 LDAPUserManager 或 LDAPGroupManage} 对 LDAP 系统执行实际查询时。默认实现使用该实例上设置的属性,如 queryGroupsForUser 和 queryUserById。 | org.flowable.ldap.LDAPQueryBuilder 的实例 | |
| groupCacheSize | 允许设置组缓存的大小。这是一个 LRU 缓存,为用户缓存组信息,从而避免每次需要获知某用户的组时都访问 LDAP 系统。 如果该值小于零,则不会实例化缓存。默认为 -1,即不进行缓存。 | int | -1 |
| groupCacheExpirationTime | 设置组缓存的过期时间,单位为毫秒。获取特定用户的组时,如果存在组缓存,这些组将按此属性设置的时长存储在缓存中。例如,00:00 获取了组信息、过期时间为 30 分钟,则 00:30 之后对该用户组的任何获取都不会来自缓存,而会重新从 LDAP 系统获取。同样,00:00 - 00:30 之间对该用户的所有组获取都将来自缓存。 | long | one hour |
使用 Active Directory 时请注意:有人反馈,对于 Active Directory,需要将 'InitialDirContext' 设置为 Context.REFERRAL。这可以通过上面所述的 customConnectionParameters map 传入。