`

Activit与LDAP的集成

阅读更多

在Activiti的User Guide(5.9)里, 有介绍activiti与LDAP的集成示例. 

 

 

<userTask id="task" name="My Task" activiti:assignee="${ldapService.findManagerForEmployee(emp)}"/>

This also works similar for candidate users and groups:

<userTask id="task" name="My Task" activiti:candidateUsers="${ldapService.findAllSales()}"/>

Note that this will only work if the return type of the invoked methods is String or Collection<String> (for candidate users and groups):

            
public class FakeLdapService {
  
  public String findManagerForEmployee(String employee) {
    return "Kermit The Frog";
  }
  
  public List<String> findAllSales() {
    return Arrays.asList("kermit", "gonzo", "fozzie");
  }

}

 

 

ldapService是在spring容器里的bean.

这种方法比较适用于单纯的为一个task指定assignee或者candidateUsers, 也就是一个或多个user.

但是对于有group关联的情况就无能为力 了.

 

 

还有一种集成方式是通过改变activiti里的UserManager和GroupManager实现来集成ldap.

这种实现方式会用到Apache LDAP API(1.0.0-M12). 

 

首先. 改变activiti配置文件.

 

activiti.cfg-mem-ldap.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
  
  	<property name="jdbcUrl" value="jdbc:h2:tcp://localhost/activiti" />
    <property name="jdbcDriver" value="org.h2.Driver" />
    <property name="jdbcUsername" value="sa" />
    <property name="jdbcPassword" value="" />
    <property name="databaseSchemaUpdate" value="true" />
    
    <property name="customSessionFactories">
      <list>
        <bean class="nanquan.test.ldap.LDAPUserManagerFactory">
          <constructor-arg ref="ldapConnectionParams" />
        </bean>
        <bean class="nanquan.test.ldap.LDAPGroupManagerFactory">
          <constructor-arg ref="ldapConnectionParams" />
        </bean>
      </list>
    </property>
    
  </bean>
  
  <bean id="ldapConnectionParams" class="nanquan.test.ldap.LDAPConnectionParams
">
    <property name="ldapServer" value="LDAP_IP" />
    <property name="ldapPort" value="389" />
    <property name="ldapUser" value="uid=admin,dc=users,dc=its" />
    <property name="ldapPassword" value="PASSWORD" />
  </bean> 

</beans>
 

在customSessionFactories属性里配置我们自定义的factories.

 

下面是两个factories和他们的服务对象.

 

LDAPUserManagerFactory.

 

 

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.persistence.entity.UserManager;

public class LDAPUserManagerFactory implements SessionFactory {

	private LDAPConnectionParams connectionParams;
	
	public LDAPUserManagerFactory(LDAPConnectionParams params) {
		this.connectionParams = params;
	}
	
	@Override
  public Class<?> getSessionType() {
	  return UserManager.class;
  }

	@Override
  public Session openSession() {
	  return new LDAPUserManager(connectionParams);
  }

}

 

LDAPUserManager.

 

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.identity.User;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.UserQueryImpl;
import org.activiti.engine.impl.persistence.entity.UserEntity;
import org.activiti.engine.impl.persistence.entity.UserManager;
import org.apache.commons.lang.StringUtils;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.directory.shared.ldap.model.cursor.EntryCursor;
import org.apache.directory.shared.ldap.model.entry.Attribute;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.message.BindRequestImpl;
import org.apache.directory.shared.ldap.model.message.BindResponse;
import org.apache.directory.shared.ldap.model.message.ResultCodeEnum;
import org.apache.directory.shared.ldap.model.message.SearchScope;
import org.apache.directory.shared.ldap.model.name.Dn;

public class LDAPUserManager extends UserManager {

//	private static final String USER_GROUP = "ou=users,ou=system";
	private static final String USER_GROUP = "dc=users,DC=ITS";

	private LDAPConnectionParams connectionParams;

	public LDAPUserManager(LDAPConnectionParams params) {
		this.connectionParams = params;
	}

	@Override
	public User createNewUser(String userId) {
		throw new ActivitiException(
				"LDAP user manager doesn't support creating a new user");
	}

	@Override
	public void insertUser(User user) {
		throw new ActivitiException(
				"LDAP user manager doesn't support inserting a new user");
	}

	@Override
	public void updateUser(User updatedUser) {
		throw new ActivitiException(
				"LDAP user manager doesn't support updating a user");
	}

	@Override
	public UserEntity findUserById(String userId) {
		throw new ActivitiException(
				"LDAP user manager doesn't support finding a user by id");
	}

	@Override
	public void deleteUser(String userId) {
		throw new ActivitiException(
				"LDAP user manager doesn't support deleting a user");
	}

	@Override
	public List<User> findUserByQueryCriteria(Object query, Page page) {

		List<User> userList = new ArrayList<User>();

		// Query is a UserQueryImpl instance
		UserQueryImpl userQuery = (UserQueryImpl) query;
		StringBuilder searchQuery = new StringBuilder();
		if (StringUtils.isNotEmpty(userQuery.getId())) {
			searchQuery.append("(uid=").append(userQuery.getId()).append(")");

		} else if (StringUtils.isNotEmpty(userQuery.getLastName())) {
			searchQuery.append("(sn=").append(userQuery.getLastName())
					.append(")");

		} else {
			searchQuery.append("(uid=*)");
		}
		LdapConnection connection = LDAPConnectionUtil
				.openConnection(connectionParams);
		try {
			EntryCursor search = connection.search(USER_GROUP,
					searchQuery.toString(), SearchScope.ONELEVEL, "*");
			while (search.next()) {
				User user = new UserEntity();
				Entry entry = search.get();
				Collection<Attribute> attributes = entry.getAttributes();
				for (Attribute attribute : attributes) {
					String key = attribute.getId();
					if ("uid".equalsIgnoreCase(key)) {
						user.setId(attribute.getString());

					} else if ("sn".equalsIgnoreCase(key)) {
						user.setLastName(attribute.getString());

					} else if ("cn".equalsIgnoreCase(key)) {
						user.setFirstName(attribute.getString().replace("cn:", "").trim());
//						user.setFirstName(attribute.getString().substring(0,
//								attribute.getString().indexOf(" ")));
					}
				}
				userList.add(user);
			}

			search.close();

		} catch (Exception e) {
			e.printStackTrace();
			throw new ActivitiException("LDAP connection search failure", e);
		}

		LDAPConnectionUtil.closeConnection(connection);

		return userList;
	}

	@Override
	public long findUserCountByQueryCriteria(Object query) {
		return findUserByQueryCriteria(query, null).size();
	}

	@Override
	public Boolean checkPassword(String userId, String password) {
		boolean credentialsValid = false;
		LdapNetworkConnection connection = new LdapNetworkConnection(
				connectionParams.getLdapServer(),
				connectionParams.getLdapPort());
		try {
//			connection.bind("uid=" + userId + ","
//					+ USER_GROUP, password);
			BindRequestImpl bindRequest = new BindRequestImpl();
			Dn dn = new Dn("uid=" + userId + ","
					+ USER_GROUP);
			bindRequest.setDn(dn );
			bindRequest.setCredentials(password);
			BindResponse response = connection.bind(bindRequest);
			if (response.getLdapResult().getResultCode() == ResultCodeEnum.SUCCESS) {
				credentialsValid = true;
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ActivitiException("LDAP connection bind failure", e);
		}

		LDAPConnectionUtil.closeConnection(connection);

		return credentialsValid;
	}
}

 

 

LDAPGroupManagerFactory.

 

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.interceptor.SessionFactory;
import org.activiti.engine.impl.persistence.entity.GroupManager;

public class LDAPGroupManagerFactory implements SessionFactory {

	private LDAPConnectionParams connectionParams;
	
	public LDAPGroupManagerFactory(LDAPConnectionParams params) {
		this.connectionParams = params;
	}
	
	@Override
  public Class<?> getSessionType() {
	  return GroupManager.class;
  }

	@Override
  public Session openSession() {
	  return new LDAPGroupManager(connectionParams);
  }

}

 

 

LDAPGroupManager 

 

 

 

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.identity.Group;
import org.activiti.engine.impl.GroupQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.persistence.entity.GroupEntity;
import org.activiti.engine.impl.persistence.entity.GroupManager;
import org.apache.commons.lang.StringUtils;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.shared.ldap.model.cursor.EntryCursor;
import org.apache.directory.shared.ldap.model.entry.Attribute;
import org.apache.directory.shared.ldap.model.entry.Entry;
import org.apache.directory.shared.ldap.model.message.SearchScope;

public class LDAPGroupManager extends GroupManager {

//	private static final String USER_ENTRY = "ou=users,ou=system";
//	private static final String GROUP_ENTRY = "ou=groups,ou=system";
	
	private static final String USER_ENTRY = "dc=users,DC=ITS";
	private static final String GROUP_ENTRY = "dc=groups,DC=ITS";

	private LDAPConnectionParams connectionParams;

	public LDAPGroupManager(LDAPConnectionParams params) {
		this.connectionParams = params;
	}

	@Override
	public Group createNewGroup(String groupId) {
		throw new ActivitiException(
				"LDAP group manager doesn't support creating a new group");
	}

	@Override
	public void insertGroup(Group group) {
		throw new ActivitiException(
				"LDAP group manager doesn't support inserting a new group");
	}

	@Override
	public void updateGroup(Group updatedGroup) {
		throw new ActivitiException(
				"LDAP group manager doesn't support updating a new group");
	}

	@Override
	public void deleteGroup(String groupId) {
		throw new ActivitiException(
				"LDAP group manager doesn't support deleting a new group");
	}

	@Override
	public List<Group> findGroupByQueryCriteria(Object query, Page page) {
		List<Group> groupList = new ArrayList<Group>();

		// Query is a GroupQueryImpl instance
		GroupQueryImpl groupQuery = (GroupQueryImpl) query;
		StringBuilder searchQuery = new StringBuilder();
		if (StringUtils.isNotEmpty(groupQuery.getId())) {
			searchQuery.append("(cn=").append(groupQuery.getId()).append(")");

		} else if (StringUtils.isNotEmpty(groupQuery.getName())) {
			searchQuery.append("(cn=").append(groupQuery.getName()).append(")");

		} else if (StringUtils.isNotEmpty(groupQuery.getUserId())) {
			searchQuery.append("(uniqueMember= uid=")
					.append(groupQuery.getUserId())
					.append("," + USER_ENTRY + ")");

		} else {
			searchQuery.append("(cn=*)");
		}
		LdapConnection connection = LDAPConnectionUtil
				.openConnection(connectionParams);
		try {
			EntryCursor search = connection.search(GROUP_ENTRY,
					searchQuery.toString(), SearchScope.ONELEVEL, "*");

			while (search.next()) {
				Group group = new GroupEntity();
				Entry entry = search.get();
				Collection<Attribute> attributes = entry.getAttributes();
				for (Attribute attribute : attributes) {
					String key = attribute.getId();
					if ("cn".equalsIgnoreCase(key)) {
						group.setId(attribute.getString());
						group.setName(attribute.getString());
					}
				}
				groupList.add(group);
			}

			search.close();

		} catch (Exception e) {
			throw new ActivitiException("LDAP connection search failure", e);
		}

		LDAPConnectionUtil.closeConnection(connection);

		return groupList;
	}

	@Override
	public long findGroupCountByQueryCriteria(Object query) {
		return findGroupByQueryCriteria(query, null).size();
	}

	@Override
	public GroupEntity findGroupById(String groupId) {
		throw new ActivitiException(
				"LDAP group manager doesn't support finding a group by id");
	}

	@Override
	public List<Group> findGroupsByUser(String userId) {
		List<Group> groupList = new ArrayList<Group>();

		LdapConnection connection = LDAPConnectionUtil
				.openConnection(connectionParams);
		try {
			EntryCursor search = connection.search(GROUP_ENTRY,
					"(uniqueMember= uid=" + userId + "," + USER_ENTRY + ")",
					SearchScope.ONELEVEL, "*");

			while (search.next()) {
				Group group = new GroupEntity();
				Entry entry = search.get();
				Collection<Attribute> attributes = entry.getAttributes();
				for (Attribute attribute : attributes) {
					String key = attribute.getId();
					if ("cn".equalsIgnoreCase(key)) {
						group.setId(attribute.getString());
						group.setName(attribute.getString());
					}
				}
				groupList.add(group);
			}

			search.close();

		} catch (Exception e) {
			throw new ActivitiException("LDAP connection search failure", e);
		}

		LDAPConnectionUtil.closeConnection(connection);

		return groupList;
	}
}

 

LDAPConnectionParams 

 

 

public class LDAPConnectionParams {
	
	private String ldapServer;
	private int ldapPort;
	private String ldapUser;
	private String ldapPassword;
	
	public String getLdapServer() {
  	return ldapServer;
  }
	public void setLdapServer(String ldapServer) {
  	this.ldapServer = ldapServer;
  }
	public int getLdapPort() {
  	return ldapPort;
  }
	public void setLdapPort(int ldapPort) {
  	this.ldapPort = ldapPort;
  }
	public String getLdapUser() {
  	return ldapUser;
  }
	public void setLdapUser(String ldapUser) {
  	this.ldapUser = ldapUser;
  }
	public String getLdapPassword() {
  	return ldapPassword;
  }
	public void setLdapPassword(String ldapPassword) {
  	this.ldapPassword = ldapPassword;
  }
}

 

LDAPConnectionUtil 

 

import org.activiti.engine.ActivitiException;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;

public class LDAPConnectionUtil {

	public static LdapConnection openConnection(LDAPConnectionParams connectionParams) {
		LdapConnection connection = new LdapNetworkConnection(connectionParams.getLdapServer(), connectionParams.getLdapPort());
	  try {
	    connection.bind(connectionParams.getLdapUser(), connectionParams.getLdapPassword());
    } catch (Exception e) {
	    throw new ActivitiException("LDAP connection open failure", e);
    }
	  return connection;
	}
	
	public static void closeConnection(LdapConnection connection) {
		try {
	  	connection.unBind();
	  	connection.close();
	  } catch (Exception e) {
	    throw new ActivitiException("LDAP connection close failure", e);
    }
	}
}

 

简单的测试类:

LdapTest 

 

 

public class LdapTest {
	
	public static void main(String[] args) {
		String path = "activiti.cfg-mem-ldap.xml";
		Resource resource = new ClassPathResource(path);
		BeanFactory beanFactory = new XmlBeanFactory(resource);
		
		LDAPConnectionParams connectionParams = (LDAPConnectionParams) beanFactory.getBean("ldapConnectionParams");
		LDAPUserManager userManager = new LDAPUserManager(connectionParams);
		LDAPGroupManager groupManager = new LDAPGroupManager(connectionParams);
		
		Boolean checkPassword = userManager.checkPassword("admin", "passw0rd");
		System.out.println(checkPassword);
		
		UserQueryImpl query = new UserQueryImpl();
		query.userId("admin");
		long size = userManager.findUserCountByQueryCriteria(query);
		System.out.println(size);
		
		GroupQueryImpl groupQuery = new GroupQueryImpl();
		groupQuery.groupId("AdminGroup");
		long groupSize = groupManager.findGroupCountByQueryCriteria(groupQuery);
		System.out.println(groupSize);
		
	}

}

 

执行一下看看是否可以正常执行.

 

需要注意的是

 

private static final String USER_GROUP = "dc=users,DC=ITS";

 

 

private static final String USER_ENTRY = "dc=users,DC=ITS";
private static final String GROUP_ENTRY = "dc=groups,DC=ITS";
 

这几个常量需要根据实际情况来调整, 当然最好可以放到配置文件里.

 

 

参考自

http://code.google.com/p/activitiinaction/source/browse/trunk/bpmn-examples/src/main/resources/chapter10/ldap/activiti.cfg-mem-ldap.xml?spec=svn205&r=205

这里面用到的Apache LDAP API比较老, 我做了一些调整.

 

 

分享到:
评论

相关推荐

    activiti-5.18使用说明

    它也支持与LDAP、Active Directory等身份验证系统集成,以强化安全性。 10. 流程版本管理: Activiti 支持流程定义的版本管理,这意味着你可以发布新版本的流程,而不会中断正在运行的实例。这对于持续改进和迭代...

    Activiti 5.13 用户手册(中文版)

    此外,还支持与 LDAP 或其他身份验证系统集成,实现统一的权限管理。 9. **持久化**:Activiti 使用关系数据库存储流程实例和历史数据,确保了数据的可靠性和可恢复性。它默认使用 H2 数据库,但也支持 MySQL、...

    Activiti 5.16 用户手册

    7. **用户和组管理**:讲解了Activiti的身份管理机制,包括用户、组的创建和管理,以及与外部身份提供者(如LDAP)的集成。 8. **监控和审计**:涵盖了Activiti提供的报表和监控工具,帮助用户分析流程执行情况,...

    activiti-5.21.0.zip

    9. **用户及组管理(User and Group Management)**:Activiti 集成了身份验证和授权功能,可以与LDAP或Active Directory等系统配合,管理用户和角色。5.21.0可能引入了新的安全特性或提升了权限控制的灵活性。 10....

    Activiti5.16中文API

    目录 1. 简介 2. 开始学习 3. 配置 4. Activiti API 5. Spring集成 6. 部署 7. BPMN 2.0介绍 8. BPMN 2.0结构 9. 表单 ...17. 集成LDAP 18. 高级功能 19. 使用Activiti-Crystalball进行流程仿真(实验)

    activiti插件(http://blog.csdn.net/y670340559/article/details/77637604)(详见)

    - **安全性插件**:增强 Activiti 的身份验证和授权功能,如与 LDAP 或其他安全框架集成。 - **审计插件**:记录流程操作的历史,便于审计和回溯。 - **表单插件**:提供自定义表单设计,提升用户体验。 - **...

    activiti工作流需要的包及其他包

    可以集成企业目录服务,如LDAP,进行身份验证和授权。 7. **其他依赖包**:除了上述核心组件,5.22.0版本可能还包括了对Spring框架的支持,用于整合到企业应用中;可能还有对MyBatis的依赖,作为持久层的实现;以及...

    Activiti Explorer工作流运行war文件

    9. **定制和扩展**:根据需求,你还可以对Activiti Explorer进行定制,比如更改主题、添加自定义模块,或者通过API与外部系统集成。 通过以上步骤,你可以在Tomcat服务器上成功运行Activiti Explorer,开始管理和...

    Activiti 学习笔记14:工作流定义的角色组

    - Activiti可以与企业的人力资源管理系统(HRM)或其他用户目录服务(如LDAP或AD)集成,以获取实时的用户和角色组信息,实现更精确的权限管理和任务分配。 7. **案例分析**: - 比如在请假申请流程中,"审批人...

    spring-boot-activiti-restful:与Activiti,Drools,LDAP,MySQL,ActiveMQ,Jasper Report,带有SwaggerUI的Restful API,AngularJS + Ionic等的Spring-boot集成

    与Activiti,Drools,LDAP,MySQL,带有SwaggerUI的Restful API,AngularJS + Ionic等的Spring-boot集成。 什么? 使用SpringBoot框架来设置RESTful API包装Activiti API。 并使用Swagger-UI可视化RESTful API,...

    activiti-6.0.zip

    此外,Activiti 还支持与其他分析工具集成,如 ELK (Elasticsearch, Logstash, Kibana) 或 Grafana,提供更深入的洞察。 5. **API 和集成**:Activiti 设计为可嵌入式的,提供丰富的 REST API 和 Java API,使得...

    latest activiti Apr 8 2015

    5. **任务分配和协作**:Activiti 支持用户角色定义和任务分配,可以与企业目录服务(如LDAP)集成,提供用户认证和授权。同时,它提供了任务工作台,使得用户能查看、接受和完成任务,并进行有效的团队协作。 6. *...

    activiti工作流

    Activiti支持与表单集成,用于收集任务执行所需的数据。表单可以是静态HTML或通过表单引擎动态生成,如使用Activiti Form或Alfresco Form Field Service。 7. **监听器(Listener)与事件(Event)** 监听器允许...

    activit实现选人效果

    7. **用户及用户组管理**:在实际应用中,用户和用户组通常由身份认证系统(如 LDAP、AD)提供,Activiti 需要与这些系统集成,以便获取和操作用户信息。 8. **流程实例的启动者**:流程实例启动时,可以设置启动者...

    Liferay平台开发使用详细PPT演示文稿

    - **API和服务**:Liferay提供丰富的RESTful API和Service API,便于与其他系统集成。 4. **安全、认证** - **安全机制**:Liferay具有内置的安全措施,包括数据加密、XSS防护和CSRF保护。 - **身份认证**:支持...

    人事管理系统

    人事管理系统,作为现代企业管理的重要工具,它集成了员工信息管理、考勤管理、薪酬福利、绩效考核、培训发展等多个功能模块,极大地提升了人力资源部门的工作效率,同时也为企业决策提供了数据支持。本文将深入解析...

    liferay-clues:Liferay 线索

    8. **集成与APIs**:Liferay提供了一整套RESTful APIs和SOAP Web服务,用于与其他系统集成。学习如何利用这些接口可以扩展Liferay的功能并与其他应用程序通信。 9. **部署与运维**:理解Liferay的部署结构,如War...

    java开源包1

    nfs-rpc是一个集成了各种知名通信框架的高性能RPC框架,目前其最好的性能为在采用grizzly作为通信框架,采用pb作为序列化/反序列化时,tps为168k次/秒。 其支持的功能主要为: 1、透明的调用远端服务器提供的功能...

    java开源包11

    nfs-rpc是一个集成了各种知名通信框架的高性能RPC框架,目前其最好的性能为在采用grizzly作为通信框架,采用pb作为序列化/反序列化时,tps为168k次/秒。 其支持的功能主要为: 1、透明的调用远端服务器提供的功能...

    java开源包2

    nfs-rpc是一个集成了各种知名通信框架的高性能RPC框架,目前其最好的性能为在采用grizzly作为通信框架,采用pb作为序列化/反序列化时,tps为168k次/秒。 其支持的功能主要为: 1、透明的调用远端服务器提供的功能...

Global site tag (gtag.js) - Google Analytics