zoukankan      html  css  js  c++  java
  • 项目中加入activiti后,用户权限管理处理的三种方式

    同步或者重构Activiti Identify用户数据的多种方案比较

    相信每个涉及到用户的系统都有一套用户权限管理平台或者模块,用来维护用户以及在系统内的功能、数据权限,我们使用的Activiti工作流引擎配套设计了包括User、Group的Identify模块,怎么和业务数据同步呢,这个问题是每个新人必问的问题之一,下面介绍几种同步方案,最后总结比较。

    方案一:调用IdentifyService接口完成同步

    参考IdentifyService接口Javadoc:http://www.activiti.org/javadocs/org/activiti/engine/IdentityService.html

    接口定义:

    [java]
    1. importjava.util.List; 
    2. importcom.foo.arch.entity.id.User;  
    3. importcom.foo.arch.service.ServiceException;  
    4. /** 
    5.  * 维护用户、角色、权限接口
    6.  * @author HenryYan 
    7.  */  
    8. public interface AccountService {  
    9.    
    10.     /** 
    11.      * 添加用户并[同步其他数据库] 
    12.      * <ul> 
    13.      * <li>step 1: 保存系统用户,同时设置和部门的关系</li> 
    14.      * <li>step 2: 同步用户信息到activiti的identity.User,同时设置角色</li> 
    15.      * </ul> 
    16.      * @param user              用户对象 
    17.      * @param orgId             部门ID 
    18.      * @param roleIds           角色ID集合 
    19.      * @param synToActiviti     是否同步到Activiti数据库,通过配置文件方式设置,使用属性:account.user.add.syntoactiviti 
    20.      * @throws OrganizationNotFoundException    关联用户和部门的时候从数据库查询不到哦啊部门对象 
    21.      * @throws  Exception                       其他未知异常 
    22.      */  
    23.     public void save(User user, Long orgId, List<long> roleIds, booleansynToActiviti)  
    24.             throws OrganizationNotFoundException, ServiceException, Exception;  
    25.        
    26.     /** 
    27.      * 删除用户 
    28.      * @param userId        用户ID 
    29.      * @param synToActiviti     是否同步到Activiti数据库,通过配置文件方式设置,使用属性:account.user.add.syntoactiviti 
    30.      * @throws Exception 
    31.      */  
    32.     public void delete(Long userId, booleansynToActiviti) throwsServiceException, Exception;  
    33.    
    34.     /** 
    35.      * 同步用户、角色数据到工作流 
    36.      * @throws Exception 
    37.      */  
    38.     public void synAllUserAndRoleToActiviti() throwsException;  
    39.    
    40.     /** 
    41.      * 删除工作流引擎Activiti的用户、角色以及关系 
    42.      * @throws Exception 
    43.      */  
    44.     public void deleteAllActivitiIdentifyData() throwsException;  
    45. }  

    同步单个接口实现片段:

    [java]
    1. @Service  
    2. @Transactional  
    3. public class AccountServiceImpl implements AccountService {   
    4.     /** 
    5.      * 保存用户信息,并且同步用户信息到activiti的identity.User和identify.Group 
    6.      * @param user              用户对象{@link User} 
    7.      * @param roleIds           用户拥有的角色ID集合 
    8.      * @param synToActiviti     是否同步数据到Activiti 
    9.      * @see Role 
    10.      */  
    11.     public void saveUser(User user, List<long> roleIds, booleansynToActiviti) {  
    12.         String userId = ObjectUtils.toString(user.getId());  
    13.    
    14.         // 保存系统用户  
    15.         accountManager.saveEntity(user);  
    16.    
    17.         // 同步数据到Activiti Identify模块  
    18.         if(synToActiviti) {  
    19.             UserQuery userQuery = identityService.createUserQuery();  
    20.             List<org.activiti.engine.identity.user> activitiUsers = userQuery.userId(userId).list();  
    21.    
    22.             if(activitiUsers.size() == 1) {  
    23.                 updateActivitiData(user, roleIds, activitiUsers.get(0));  
    24.             }elseif (activitiUsers.size() > 1) {  
    25.                 String errorMsg = "发现重复用户:id="+ userId;  
    26.                 logger.error(errorMsg);  
    27.                 thrownew RuntimeException(errorMsg);  
    28.             }else{  
    29.                 newActivitiUser(user, roleIds);  
    30.             }  
    31.         }  
    32.    
    33.     }  
    34.    
    35.     /** 
    36.      * 添加工作流用户以及角色 
    37.      * @param user      用户对象{@link User} 
    38.      * @param roleIds   用户拥有的角色ID集合 
    39.      */  
    40.     private void newActivitiUser(User user, List<long> roleIds) {  
    41.         String userId = user.getId().toString();  
    42.    
    43.         // 添加用户  
    44.         saveActivitiUser(user);  
    45.    
    46.         // 添加membership  
    47.         addMembershipToIdentify(roleIds, userId);  
    48.     }  
    49.    
    50.     /** 
    51.      * 添加一个用户到Activiti {@link org.activiti.engine.identity.User} 
    52.      * @param user  用户对象, {@link User} 
    53.      */  
    54.     private void saveActivitiUser(User user) {  
    55.         String userId = user.getId().toString();  
    56.         org.activiti.engine.identity.User activitiUser = identityService.newUser(userId);  
    57.         cloneAndSaveActivitiUser(user, activitiUser);  
    58.         logger.debug("add activiti user: {}", ToStringBuilder.reflectionToString(activitiUser));  
    59.     }  
    60.    
    61.     /** 
    62.      * 添加Activiti Identify的用户于组关系 
    63.      * @param roleIds   角色ID集合 
    64.      * @param userId    用户ID 
    65.      */  
    66.     private void addMembershipToIdentify(List<long> roleIds, String userId) {  
    67.         for(Long roleId : roleIds) {  
    68.             Role role = roleManager.getEntity(roleId);  
    69.             logger.debug("add role to activit: {}", role);  
    70.             identityService.createMembership(userId, role.getEnName());  
    71.         }  
    72.     }  
    73.    
    74.     /** 
    75.      * 更新工作流用户以及角色 
    76.      * @param user          用户对象{@link User} 
    77.      * @param roleIds       用户拥有的角色ID集合 
    78.      * @param activitiUser  Activiti引擎的用户对象,{@link org.activiti.engine.identity.User} 
    79.      */  
    80.     private void updateActivitiData(User user, List<long> roleIds, org.activiti.engine.identity.User activitiUser) {  
    81.    
    82.         String userId = user.getId().toString();  
    83.    
    84.         // 更新用户主体信息  
    85.         cloneAndSaveActivitiUser(user, activitiUser);  
    86.    
    87.         // 删除用户的membership  
    88.         List<group> activitiGroups = identityService.createGroupQuery().groupMember(userId).list();  
    89.         for(Group group : activitiGroups) {  
    90.             logger.debug("delete group from activit: {}", ToStringBuilder.reflectionToString(group));  
    91.             identityService.deleteMembership(userId, group.getId());  
    92.         }  
    93.    
    94.         // 添加membership  
    95.         addMembershipToIdentify(roleIds, userId);  
    96.     }  
    97.    
    98.     /** 
    99.      * 使用系统用户对象属性设置到Activiti User对象中 
    100.      * @param user          系统用户对象 
    101.      * @param activitiUser  Activiti User 
    102.      */  
    103.     private void cloneAndSaveActivitiUser(User user, org.activiti.engine.identity.User activitiUser) {  
    104.         activitiUser.setFirstName(user.getName());  
    105.         activitiUser.setLastName(StringUtils.EMPTY);  
    106.         activitiUser.setPassword(StringUtils.EMPTY);  
    107.         activitiUser.setEmail(user.getEmail());  
    108.         identityService.saveUser(activitiUser);  
    109.     }  
    110.    
    111.     @Override  
    112.     public void delete(Long userId, booleansynToActiviti, booleansynToChecking) throwsServiceException, Exception {  
    113.         // 查询需要删除的用户对象  
    114.         User user = accountManager.getEntity(userId);  
    115.         if(user == null) {  
    116.             thrownew ServiceException("删除用户时,找不到ID为"+ userId + "的用户");  
    117.         }  
    118.    
    119.         /** 
    120.          * 同步删除Activiti User Group 
    121.          */  
    122.         if(synToActiviti) {  
    123.             // 同步删除Activiti User  
    124.             List<role> roleList = user.getRoleList();  
    125.             for(Role role : roleList) {  
    126.                 identityService.deleteMembership(userId.toString(), role.getEnName());  
    127.             }  
    128.    
    129.             // 同步删除Activiti User  
    130.             identityService.deleteUser(userId.toString());  
    131.         }  
    132.    
    133.         // 删除本系统用户  
    134.         accountManager.deleteUser(userId);  
    135.    
    136.         // 删除考勤机用户  
    137.         if(synToChecking) {  
    138.             checkingAccountManager.deleteEntity(userId);  
    139.         }  
    140.     }  

    同步全部数据接口实现片段:

    同步全部数据步骤:

    • 删除Activiti的User、Group、Membership数据

    • 复制Role对象数据到Group

    • 复制用户数据以及Membership数据


    ActivitiIdentifyCommonDao.java
    [java]
    1. public class ActivitiIdentifyCommonDao {  
    2.     protectedLogger logger = LoggerFactory.getLogger(getClass());  
    3.     @Autowired  
    4.     private JdbcTemplate jdbcTemplate;  
    5.     /** 
    6.      * 删除用户和组的关系 
    7.      */  
    8.     public void deleteAllUser() {  
    9.         String sql = "delete from ACT_ID_USER";  
    10.         jdbcTemplate.execute(sql);  
    11.         logger.debug("deleted from activiti user.");  
    12.     }  
    13.    
    14.     /** 
    15.      * 删除用户和组的关系 
    16.      */  
    17.     public void deleteAllRole() {  
    18.         String sql = "delete from ACT_ID_GROUP";  
    19.         jdbcTemplate.execute(sql);  
    20.         logger.debug("deleted from activiti group.");  
    21.     }  
    22.    
    23.     /** 
    24.      * 删除用户和组的关系 
    25.      */  
    26.     public void deleteAllMemerShip() {  
    27.         String sql = "delete from ACT_ID_MEMBERSHIP";  
    28.         jdbcTemplate.execute(sql);  
    29.         logger.debug("deleted from activiti membership.");  
    30.     }  
    31. }  
    ActivitiIdentifyService.java(下面两段代码重复)
    1. public class ActivitiIdentifyService extends AbstractBaseService {  

    2.     @Autowired  
    3.     protected ActivitiIdentifyCommonDao activitiIdentifyCommonDao;  

    4.     /** 
    5.      * 删除用户和组的关系 
    6.      */  
    7.     public void deleteAllUser() {  
    8.         activitiIdentifyCommonDao.deleteAllUser();  
    9.     }  
    10.        
    11.     /** 
    12.      * 删除用户和组的关系 
    13.      */  
    14.     public void deleteAllRole() {  
    15.         activitiIdentifyCommonDao.deleteAllRole();  
    16.     }  
    17.        
    18.     /** 
    19.      * 删除用户和组的关系 
    20.      */  
    21.     public void deleteAllMemerShip() {  
    22.         activitiIdentifyCommonDao.deleteAllMemerShip();  
    23.     }  
    24. }  

    publicclass ActivitiIdentifyService extendsAbstractBaseService {
         
        @Autowired
        protectedActivitiIdentifyCommonDao activitiIdentifyCommonDao;
         
        /**
         * 删除用户和组的关系
         */
        publicvoid deleteAllUser() {
            activitiIdentifyCommonDao.deleteAllUser();
        }
         
        /**
         * 删除用户和组的关系
         */
        publicvoid deleteAllRole() {
            activitiIdentifyCommonDao.deleteAllRole();
        }
         
        /**
         * 删除用户和组的关系
         */
        publicvoid deleteAllMemerShip() {
            activitiIdentifyCommonDao.deleteAllMemerShip();
        }
    }
    AccountServiceImpl.java(下面两段代码重复)
    1. public  class AccountServiceImpl implements AccountService { 
    2.   
    3. @Override  
    4.     public void synAllUserAndRoleToActiviti() throwsException {  
    5.    
    6.         // 清空工作流用户、角色以及关系  
    7.         deleteAllActivitiIdentifyData();  
    8.    
    9.         // 复制角色数据  
    10.         synRoleToActiviti();  
    11.    
    12.         // 复制用户以及关系数据  
    13.         synUserWithRoleToActiviti();  
    14.     }  
    15.    
    16.     /** 
    17.      * 复制用户以及关系数据 
    18.      */  
    19.     private void synUserWithRoleToActiviti() {  
    20.         List<user> allUser = accountManager.getAll();  
    21.         for(User user : allUser) {  
    22.             String userId = user.getId().toString();  
    23.    
    24.             // 添加一个用户到Activiti  
    25.             saveActivitiUser(user);  
    26.    
    27.             // 角色和用户的关系  
    28.             List<role> roleList = user.getRoleList();  
    29.             for(Role role : roleList) {  
    30.                 identityService.createMembership(userId, role.getEnName());  
    31.                 logger.debug("add membership {user: {}, role: {}}", userId, role.getEnName());  
    32.             }  
    33.         }  
    34.     }  
    35.    
    36.     /** 
    37.      * 同步所有角色数据到{@link Group} 
    38.      */  
    39.     private void synRoleToActiviti() {  
    40.         List<role> allRole = roleManager.getAll();  
    41.         for(Role role : allRole) {  
    42.             String groupId = role.getEnName().toString();  
    43.             Group group = identityService.newGroup(groupId);  
    44.             group.setName(role.getName());  
    45.             group.setType(role.getType());  
    46.             identityService.saveGroup(group);  
    47.         }  
    48.     }  
    49.    
    50.     @Override  
    51.     public void deleteAllActivitiIdentifyData() throwsException {  
    52.         activitiIdentifyService.deleteAllMemerShip();  
    53.         activitiIdentifyService.deleteAllRole();  
    54.         activitiIdentifyService.deleteAllUser();  
    55.     }  
    56. }  

    publicclass AccountServiceImpl implementsAccountService {
    @Override
        publicvoid synAllUserAndRoleToActiviti() throwsException {
     
            // 清空工作流用户、角色以及关系
            deleteAllActivitiIdentifyData();
     
            // 复制角色数据
            synRoleToActiviti();
     
            // 复制用户以及关系数据
            synUserWithRoleToActiviti();
        }
     
        /**
         * 复制用户以及关系数据
         */
        privatevoid synUserWithRoleToActiviti() {
            List<user> allUser = accountManager.getAll();
            for(User user : allUser) {
                String userId = user.getId().toString();
     
                // 添加一个用户到Activiti
                saveActivitiUser(user);
     
                // 角色和用户的关系
                List<role> roleList = user.getRoleList();
                for(Role role : roleList) {
                    identityService.createMembership(userId, role.getEnName());
                    logger.debug("add membership {user: {}, role: {}}", userId, role.getEnName());
                }
            }
        }
     
        /**
         * 同步所有角色数据到{@link Group}
         */
        privatevoid synRoleToActiviti() {
            List<role> allRole = roleManager.getAll();
            for(Role role : allRole) {
                String groupId = role.getEnName().toString();
                Group group = identityService.newGroup(groupId);
                group.setName(role.getName());
                group.setType(role.getType());
                identityService.saveGroup(group);
            }
        }
     
        @Override
        publicvoid deleteAllActivitiIdentifyData() throwsException {
            activitiIdentifyService.deleteAllMemerShip();
            activitiIdentifyService.deleteAllRole();
            activitiIdentifyService.deleteAllUser();
        }
    }

    方案二:覆盖IdentifyService接口的实现

    此方法覆盖IdentifyService接口的默认实现类:org.activiti.engine.impl.IdentityServiceImpl

    读者可以根据现有的用户管理接口实现覆盖IdentityServiceImpl的每个方法的默认实现,这样就等于放弃使用系列表:ACT_ID_。

    此方法不再提供代码,请读者自行根据现有接口逐一实现接口定义的功能。

    方案三:用视图覆盖同名的ACT_ID_系列表

    此方案和第二种类似,放弃使用系列表:ACT_ID_,创建同名的视图。

    1.删除已创建的ACT_ID_*表

    创建视图必须删除引擎自动创建的ACT_ID_*表,否则不能创建视图。

    2.创建视图:

    • ACT_ID_GROUP
    • ACT_ID_INFO
    • ACT_ID_MEMBERSHIP
    • ACT_ID_USER

    创建的视图要保证数据类型一致,例如用户的ACT_ID_MEMBERSHIP表的两个字段都是字符型,一般系统中都是用NUMBER作为用户、角色的主键类型,所以创建视图的时候要把数字类型转换为字符型。

    3.修改引擎默认配置

    在引擎配置中设置属性dbIdentityUsedfalse即可。

    1. <beanidbeanid="processEngineConfiguration"class="org.activiti.spring.SpringProcessEngineConfiguration">  
    2.     ...  
    3.     <propertynamepropertyname="dbIdentityUsed"ref="false">  
    4.     ...  
    5. </property></bean>  
    <beanid="processEngineConfiguration"class="org.activiti.spring.SpringProcessEngineConfiguration">
        ...
        <propertyname="dbIdentityUsed"ref="false">
        ...
    </property></bean>

    总结
    • 方案:不破坏、不修改源码,面向接口编程推荐

    • 方案:放弃原有的Identify模块,使用自定义的实现,特殊情况可以使用此方式;

    • 方案:不需要编写Java代码,只需要创建同名视图即可对于现有系统的集成、强烈推荐

  • 相关阅读:
    CSUFT 1002 Robot Navigation
    CSUFT 1003 All Your Base
    Uva 1599 最佳路径
    Uva 10129 单词
    欧拉回路
    Uva 10305 给任务排序
    uva 816 Abbott的复仇
    Uva 1103 古代象形文字
    Uva 10118 免费糖果
    Uva 725 除法
  • 原文地址:https://www.cnblogs.com/llhl/p/9648691.html
Copyright © 2011-2022 走看看