Activiti 自定义用户管理和组管理

来源:互联网 发布:农村淘宝店在哪申请 编辑:程序博客网 时间:2024/06/13 12:39

Activiti 自定义用户管理和组管理

最近在研究如何自定义Activiti用户和组管理模块(Example:连接keystone用户管理模块,实际当中使用时当然可以将keystone转变为其他第三方用户管理模块),整理了一下心得,避免后人踩坑。

本文站立在activiti源代码中的activiti-webapp-rest2模块的肩膀上。

借助大神—Nadav Azaria— 2012年的文章《Activiti Authentication And Identity Management Tutorial》 开始全新的自定义之旅。

Activiti为我们提供的这样的入口,想想activiti的ldap模块的原理就应该清楚了,不过仍然疑惑的是如何才能构建activiti能够识别的class,并且如何向activiti引擎进行注册?

很显然,SessionFactory为我们提供了这样的接口。

首先,建立OwnUserManagerFactory和OwnGroupManagerFactory 均需继承activiti的SessionFactory。稍后我们将实现ManagerFactory中引用的class。

public class OwnUserManagerFactory implements SessionFactory {    private KeystoneConnection keystoneConnection;    public OwnUserManagerFactory (KeystoneConnection keystoneConnection) {        this.keystoneConnection = keystoneConnection;    }    public Class<?> getSessionType() {        return UserIdentityManager.class;    }    public Session openSession() {        return new OwnUserManager(this.getKeystoneConnection());    }    public KeystoneConnection getKeystoneConnection() {        return keystoneConnection;    }    public void setKeystoneConnection(KeystoneConnection keystoneConnection) {        this.keystoneConnection = keystoneConnection;    }}
public class OwnGroupMagagerFactory implements SessionFactory {    private KeystoneConnection keystoneConnection;    public OwnGroupMagagerFactory(KeystoneConnection keystoneConnection) {        this.keystoneConnection = keystoneConnection;    }    @Override    public Class<?> getSessionType() {        return GroupIdentityManager.class;    }    @Override    public Session openSession() {        return new OwnGroupManager(this.getKeystoneConnection());    }    public KeystoneConnection getKeystoneConnection() {        return keystoneConnection;    }    public void setKeystoneConnection(KeystoneConnection keystoneConnection) {        this.keystoneConnection = keystoneConnection;    }}

其次,建立OwnUserManager和OwnGroupManager,其中,我们需要自定义用户模块的查询方法,在findUserByQueryCriteria中,任何与第三方用户管理模块的通讯方式都是可以让我们自己实现的。

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.UserEntityManager;public class OwnUserManager extends UserEntityManager {    private KeystoneConnection keystoneConnection;    public OwnUserManager(KeystoneConnection keystoneConnection) {        this.keystoneConnection = keystoneConnection;    }    @Override    public User createNewUser(String userId) {        return super.createNewUser(userId);//      throw new ActivitiException("User manager doesn't support creating a newe user");    }    @Override    public void insertUser(User user) {        super.insertUser(user);//      throw new ActivitiException("User manager doesn't support inserting a newe user");    }    @Override    public void updateUser(User updatedUser) {        super.updateUser(updatedUser);//      throw new ActivitiException("User manager doesn't support updating a newe user");    }    @Override    public User findUserById(String userId) {        return super.findUserById(userId);//      throw new ActivitiException("User manager doesn't support finding an user by id");    }    @Override    public void deleteUser(String userId) {        throw new ActivitiException("User manager doesn't support deleting a newe user");    }    @Override    public List<User> findUserByQueryCriteria(UserQueryImpl query, Page page) {        System.out.println(                "start to findUserByQueryCriteria.....................!!!!!!_----------------------------------------------------");        // use your own method or third party method...        return super.findUserByQueryCriteria(query, page);    }    @Override    public List<User> findUsersByNativeQuery(Map<String, Object> parameterMap, int firstResult, int maxResults) {        System.out.println(                "start to findUsersByNativeQuery.....................!!!!!!_----------------------------------------------------");        // use your own method or third party method...        return super.findUsersByNativeQuery(parameterMap, firstResult, maxResults);    }    @Override    public long findUserCountByQueryCriteria(UserQueryImpl query) {        return super.findUserCountByQueryCriteria(query);//      return findUserByQueryCriteria(query, null).size();    }    @Override    public Boolean checkPassword(String userId, String password) {        // now return true, means that ignoring the password verification        return true;    }}

checkPassword 方法return true,即为跳过spring security用户验证,

public class OwnGroupManager extends GroupEntityManager {    private KeystoneConnection keystoneConnection;    public OwnGroupManager(KeystoneConnection keystoneConnection) {        this.keystoneConnection = keystoneConnection;    }     @Override    public void insertGroup(Group group) {        throw new ActivitiException("My group manager doesn't support inserting a new group");    }    @Override    public void updateGroup(Group updatedGroup) {        throw new ActivitiException("My group manager doesn't support updating a new group");    }    @Override    public void deleteGroup(String groupId) {        throw new ActivitiException("My group manager doesn't support deleting a new group");    }    @Override    public List<Group> findGroupByQueryCriteria(GroupQueryImpl query, Page page) {        // sometimes to implement how to query the Group//      return super.findGroupByQueryCriteria(query, page);        List<Group> groups = new ArrayList<Group>();        GroupEntity ge = new GroupEntity();        ge.setId("admin");        ge.setRevision(1);        ge.setName("Administrators");        ge.setType("security-role");        groups.add(ge);        return groups;    }    @Override    public long findGroupCountByQueryCriteria(GroupQueryImpl query) {        // TODO Auto-generated method stub        return super.findGroupCountByQueryCriteria(query);    }    @Override    public List<Group> findGroupsByUser(String userId) {        throw new ActivitiException("My group manager doesn't support finding a group");    }}

然后,建立KeystoneConnection,当然可以换成第三方或者自定义的其它用户管理模块。
简简单单,它就是一个POJO。

在findGroupByQueryCriteria和findUserByQueryCriteria可以调用基于KeystoneConnection的用户管理模块

public class KeystoneConnection {    private String protocal;    private String address;    private String port;    public KeystoneConnection() {    }    public KeystoneConnection(String protocal, String address, String port) {        this.protocal = protocal;        this.address = address;        this.port = port;    }    public String getKeystoneUrl(String url) {        return this.protocal + "://" + this.address + ":" + this.port + url;    }    // getter and setter}

最后,需要告诉activiti引擎,如何才能识别我们在第一步中实现的两个工厂类,也就是注册的过程。我们扩展了原先conf中的ActivitiEngineConfiguration类,当然,如果在spring的xml文件中配置也是ok的。

@Configurationpublic class ActivitiEngineConfiguration
@Bean(name = "processEngineConfiguration")    public ProcessEngineConfigurationImpl processEngineConfiguration() {        SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();        // add following configuration        // load the custom manager session factory        List<SessionFactory> customSessionFactories = new ArrayList<SessionFactory>();        customSessionFactories.add(new OwnUserManagerFactory(keystoneConnection()));        customSessionFactories.add(new OwnGroupMagagerFactory(keystoneConnection()));        processEngineConfiguration.setCustomSessionFactories(customSessionFactories);        return processEngineConfiguration;    }

结论
读一读源码,体会很深。
原理很简单,activiti的sessionFactory模块维护了一个

HashMap<SessionType, Session>

我们后来注册的这两个sub sessionFactory会覆盖activiti引擎初始化时所加载的其本身的关系映射,运行时每次读取的当然是我们自己定义的sessionFactory了。

1 0
原创粉丝点击