<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    當柳上原的風吹向天際的時候...

    真正的快樂來源于創造

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
    權限系統是稍成規模的系統中一個必不可少的部分,操作的可否執行,流程的具體走向,業務的具體步驟都會涉及權限的處理。
    具體來說有兩種權限的控制方式:一種是等級權限控制方式,一種是角色權限控制方式。前者可用于范圍控制,適用于用戶權力大小不同的場合;后者可用于單點控制,適用于用戶權力多寡有異的場合。現實世界中,軍隊中官銜類似于等級權限控制,現代企業中各司其職的權力分配類似于角色控制。范圍控制前面已經提到過了,今天來談談角色權限控制。

    角色權限控制是把單項權限一項項的賦予用戶,如同現實世界中把具體職位一個個的賦予某個員工一樣。在他執行操作前,先看他是否擁有執行此操作的權限,如果有則執行,否則不執行。

    在這里我們還是采用上一講的業務,實現IDocService的實現類DocService,但要把等級權限控制方式修改成角色權限控制方式,原來的處置是用戶權限高于某個值就能執行操作,現在如果一個用戶有“添加”角色,他就可以添加文檔;如果他缺乏“修改”角色,他就不能修改文檔。

    實現用戶角色權限控制并不復雜,下面請看具體思路:
    1.創建兩個領域對象類:用戶類User和角色類Role,他們之間是一對多的關系,他們對應的表用主外鍵關聯起來。使用Hibernate很容易實現這一關系。
    2.使用AOP,實現IDocService接口的實現類DocService的代理,使用UserRoleController作為前置通知,角色權限控制放入其中。
    3. UserRoleController中,查看用戶是否有執行某項操作的權限,沒有則拋出異常NoRoleException,否則執行的DocService中的函數。

    領域對象類的基類BaseDomainObj,User,Role,Doc等都是它的子類。
    package com.heyang.domain;

    /**
     * 領域對象基類
     * 
    @author 何楊
     * 
    @version 1.00
     * 
    @since 2009-1-5 上午10:26:32
     *
     
    */

    public abstract class BaseDomainObj{
        
    // ID
        protected long id;
        
        
    // 名稱
        protected String name;
        
        
    public String toString(){
            
    return name;
        }


        
    public long getId() {
            
    return id;
        }


        
    public void setId(long id) {
            
    this.id = id;
        }
            

        
    public String getName() {
            
    return name;
        }


        
    public void setName(String name) {
            
    this.name = name;
        }

    }

    User類
    package com.heyang.domain;

    import java.util.LinkedHashSet;
    import java.util.Set;

    /**
     * 領域對象用戶類
     * 
    @author 何楊
     * 
    @version 1.00
     * 
    @since 2009-1-5 上午10:23:25
     *
     
    */

    public class User extends BaseDomainObj{
        
    // 用戶所擁有的權限
        private Set<Role> roles=new LinkedHashSet<Role>();
        
        
    public User(){
            
        }

        
        
    public User(String name){
            
    this.name=name;
        }

            
        
    /**
         * 判斷用戶是否擁有角色。若參數角色名在用戶角色集合中能找到則認為用戶有此角色,即名相同則有,否則無
         * 
    @param roleName :角色名
         * 
    @return
         
    */

        
    public boolean hasRole(String roleName){
            
    for(Role role:roles){
                
    if(role.getName().equals(roleName)){
                    
    return true;
                }

            }

            
            
    return false;
        }


        
    public Set<Role> getRoles() {
            
    return roles;
        }


        
    public void setRoles(Set<Role> roles) {
            
    this.roles = roles;
        }
        
    }

    User類的Hibernate映射文件,Set部分是關鍵:
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
    >
    <hibernate-mapping package="org.hibernate.auction">
      
    <class name="com.heyang.domain.User"
        table
    ="AOPRoleSample_User" lazy="false">
        
    <id name="id" column="ID" >
          
    <generator class="native"/>
        
    </id>
        
    <property name="name" column="name" />
        
    <set name="roles" cascade="all" lazy="false">
          
    <key column="userid"/>
          
    <one-to-many class="com.heyang.domain.Role"/>
        
    </set>
      
    </class>
    </hibernate-mapping>

    Role類:
    package com.heyang.domain;

    /**
     * 領域對象角色類
     * 
    @author 何楊
     * 
    @version 1.00
     * 
    @since 2009-1-5 上午10:32:16
     *
     
    */

    public class Role extends BaseDomainObj{
      
    public Role(){
        
      }

      
      
    public Role(String name){
        
    this.name=name;
      }

    }


    Role類的映射文件:
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
      "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
      "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
    >
    <hibernate-mapping package="org.hibernate.auction">
      
    <class name="com.heyang.domain.Role"
        table
    ="AOPRoleSample_Role" lazy="false">
        
    <id name="id" column="ID" >
          
    <generator class="native"/>
        
    </id>
        
    <property name="name" column="name" />
      
    </class>
    </hibernate-mapping>

    DocService類,有了AOP的幫忙,其中不需要任何權限控制的代碼,它甚至不知道權限控制子系統的存在
    public class DocService extends BaseService implements IDocService {
      
    /**
       * 按ID取得文檔
       * 
    @param id
       * 
    @return
       
    */

      
    public Doc getDoc(long id){
        
    return (Doc)dao.get(Doc.class,id);
      }

      
      
    public void add(Doc doc, User user) {
        System.out.println(
    "" + doc + "交由dao處理(存入數據庫)");
        dao.create(doc);
      }


      
    public void delete(Doc doc, User user) {
        System.out.println(
    "" + doc + "交由dao處理(從數據庫刪除)");
        dao.delete(doc);
      }


      
    public void update(Doc doc, User user) {
        System.out.println(
    "" + doc + "交由dao處理(修改數據庫中對應的記錄)");
        dao.update(doc);
      }

    }


    UserRoleController類,它作為DocService的前置處理器,在真正的數據庫操作開始前進行權限處理
    package com.heyang.service;

    import java.lang.reflect.Method;

    import org.springframework.aop.MethodBeforeAdvice;

    import com.heyang.domain.User;
    import com.heyang.exception.NoRoleException;

    /**
     * 實現角色子系統---用戶角色控制
     * 
    @author: 何楊(heyang78@gmail.com)
     * @date: 2009-1-2-下午04:19:13
     
    */

    public class UserRoleController implements MethodBeforeAdvice{
        
    private String addDocRoleName;
        
    private String deleteDocRoleName;
        
    private String updateDocRoleName;
            
        
    /**
         * 在IDocService的實際方法開始前進行前置處理--用戶角色檢查
         
    */

        
    public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
            
    // 取得方法名
            String mothodName=arg0.getName();
            
            
    // 取得用戶
            User user=null;        
            
    if(arg1.length>1){
                user
    =(User)arg1[1];        
            }

            
            
    // 根據方法名判斷用戶是否擁有所需要的角色,否則拋出異常
            if("add".equals(mothodName)){
                
    if(user.hasRole(addDocRoleName)==false){
                    
    throw new NoRoleException("用戶"+user+"必須擁有‘添加’角色才能執行添加文檔操作");
                }

            }

            
    else if("delete".equals(mothodName)){
                
    if(user.hasRole(deleteDocRoleName)==false){
                    
    throw new NoRoleException("用戶"+user+"必須擁有‘刪除’角色才能執行刪除文檔操作");
                }

            }

            
    else if("update".equals(mothodName)){
                
    if(user.hasRole(updateDocRoleName)==false){
                    
    throw new NoRoleException("用戶"+user+"必須擁有‘修改’角色才能執行修改文檔操作");
                }

            }

        }



        
    public String getAddDocRoleName() {
            
    return addDocRoleName;
        }



        
    public void setAddDocRoleName(String addDocRoleName) {
            
    this.addDocRoleName = addDocRoleName;
        }



        
    public String getDeleteDocRoleName() {
            
    return deleteDocRoleName;
        }



        
    public void setDeleteDocRoleName(String deleteDocRoleName) {
            
    this.deleteDocRoleName = deleteDocRoleName;
        }



        
    public String getUpdateDocRoleName() {
            
    return updateDocRoleName;
        }



        
    public void setUpdateDocRoleName(String updateDocRoleName) {
            
    this.updateDocRoleName = updateDocRoleName;
        }

    }

    全體配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
        
    <!-- 數據源 -->
        
    <bean id="dataSource"
            class
    ="org.springframework.jdbc.datasource.DriverManagerDataSource">
            
    <property name="driverClassName"
                value
    ="org.gjt.mm.mysql.Driver">
            
    </property>
            
    <property name="url" value="jdbc:mysql://127.0.0.1/test">
            
    </property>
            
    <property name="username" value="root"></property>
            
    <property name="password" value="hy"></property>
        
    </bean>
        
        
    <!-- Hibernate Session Factory,使用了上面配置的數據源 -->
        
    <bean id="sessionFactory"
            class
    ="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
            
    <property name="dataSource">
                
    <ref bean="dataSource"/>
            
    </property>
            
    <property name="mappingResources">
              
    <list>
                
    <value>com/heyang/domain/User.hbm.xml</value>
                
    <value>com/heyang/domain/Role.hbm.xml</value>
                
    <value>com/heyang/domain/Doc.hbm.xml</value>
              
    </list>
            
    </property>
            
    <property name="hibernateProperties">
                
    <value>
                    hibernate.hbm2ddl.auto=Acreate
                    hibernate.dialect=org.hibernate.dialect.MySQLDialect
                    hibernate.show_sql=true    
                    hibernate.format_sql=true                            
                
    </value>
            
    </property>        
        
    </bean>
        
        
    <!-- Hibernate Template,使用了上面配置的sessionFactory -->
        
    <bean id="hibernateTemplate"
            class
    ="org.springframework.orm.hibernate3.HibernateTemplate">
            
    <property name="sessionFactory">
                
    <ref bean="sessionFactory"/>
            
    </property>
        
    </bean>
        
        
    <!-- 使用了上面配置的hibernateTemplate的BaseDao -->
        
    <bean id="dao" class="com.heyang.dao.BaseDao">
            
    <property name="hibernateTemplate">
                
    <ref bean="hibernateTemplate"/>
            
    </property>
        
    </bean>
        
        
    <!-- 使用了上面配置的dao的UserService -->
        
    <bean id="userService" class="com.heyang.service.UserService">
            
    <property name="domainClass">
                
    <value>User</value>
            
    </property>
            
    <property name="dao">
                
    <ref bean="dao"/>
            
    </property>
        
    </bean>
        
        
    <!-- 用于文件處理的IDocService實現類DocService -->
        
    <bean id="docService" class="com.heyang.service.DocService">
            
    <property name="dao">
                
    <ref bean="dao"/>
            
    </property>
        
    </bean>
        
        
    <!-- 在執行docService的實際方法前進行用戶角色檢查 -->
        
    <bean id="userRoleController" class="com.heyang.service.UserRoleController">
            
    <property name="addDocRoleName" value="添加" />
            
    <property name="deleteDocRoleName" value="刪除" />
            
    <property name="updateDocRoleName" value="修改" />        
        
    </bean>
        
        
    <!-- docService的代理對象 -->
        
    <bean id="docServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
            
    <property name="proxyInterfaces">
                
    <value>com.heyang.service.IDocService</value>
            
    </property>
            
    <property name="interceptorNames">
                
    <list>
                    
    <value>userRoleController</value>
                
    </list>
            
    </property>
            
    <property name="target">
                
    <ref bean="docService"/>
            
    </property>
        
    </bean>
    </beans>

    模擬處理:
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            
            UserService userService
    =(UserService)ctx.getBean("userService");
            IDocService docService
    =(IDocService)ctx.getBean("docServiceProxy");
            
            User user
    =userService.getUser(1);
            Doc doc1;
            
            
    // 模擬添加操作
            doc1=new Doc("論次貸危機對美國的影響");
            
    try{
                docService.add(doc1, user);
            }

            
    catch(NoRoleException ex){
                ex.printStackTrace();
            }

            
            
    // 模擬修改操作
            doc1=docService.getDoc(1);
            doc1.setName(
    "論次貸危機對中國的影響");
            
    try{
                docService.update(doc1, user);
            }

            
    catch(NoRoleException ex){
                ex.printStackTrace();
            }

            
            
    // 模擬刪除操作
            doc1=docService.getDoc(1);
            doc1.setName(
    "論次貸危機對世界的影響");
            
    try{
                docService.delete(doc1, user);
            }

            
    catch(NoRoleException ex){
                ex.printStackTrace();
            }

    小結:

    權限子系統是企業應用中不可或缺的環節,它具體的權限控制方式有兩種:一種是等級權限控制方式,一種是角色權限控制方式,其他復雜的權限系統都可以由它們組合而來。

    由于業務控制的關系,權限子系統和其他業務子系統的最容易耦合在一起,久而久之會對程序的可讀性,可維護性帶來消極影響,而AOP恰好能幫助我們有效降低權限子系統和其他業務子系統的耦合,實現他們之間的離散化。因此,AOP值得我們認真掌握,尤其是其背后面向方面編程的精神。


    代碼下載:
    http://www.tkk7.com/Files/heyang/AOPRoleSample20090106060255.rar

    需要的庫請自行補充(基本ProjectTodolist的lib全有)。
    posted on 2009-01-05 21:38 何楊 閱讀(2035) 評論(2)  編輯  收藏

    Feedback

    # re: 用戶角色權限控制的實現 2009-04-22 20:24 小何
    有沒有角色,用戶控制權限(細粒度)的例子,我最近也在做一個項目的權限控制,但找不到好的例子,有就發給我一下,郵箱是:hgyang_1984@126.com,謝謝~  回復  更多評論
      

    # re: 用戶角色權限控制的實現 2009-04-22 22:44 hy
    http://www.tkk7.com/heyang/archive/2009/04/02/263471.html

      回復  更多評論
      


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 国产亚洲精品免费| 最好2018中文免费视频| 国产亚洲av人片在线观看| 国色精品卡一卡2卡3卡4卡免费| 两个人看的www视频免费完整版| 亚洲成在人线在线播放无码| 久久精品国产亚洲AV高清热| 亚洲色欲久久久久综合网| 免费毛片网站在线观看| 亚洲午夜福利精品无码| 最近中文字幕免费mv视频7| 色欲A∨无码蜜臀AV免费播| 99在线免费视频| 人成免费在线视频| 欧洲亚洲综合一区二区三区 | 男人的天堂av亚洲一区2区| 亚洲国产美女精品久久久久| 亚洲AV日韩AV永久无码下载| 国产亚洲精品高清在线| 99久久久国产精品免费牛牛四川| 丰满人妻一区二区三区免费视频 | 亚洲AV无码不卡在线观看下载| 扒开双腿猛进入爽爽免费视频| 无码精品A∨在线观看免费| 国产人成免费视频网站| 亚洲免费福利在线视频| 日本免费人成在线网站| 日本片免费观看一区二区| aⅴ在线免费观看| 69成人免费视频| 好吊妞998视频免费观看在线| 三年片在线观看免费观看高清电影| 无码av免费毛片一区二区| 两性刺激生活片免费视频| 免费成人福利视频| 国拍在线精品视频免费观看| 在线a毛片免费视频观看| 免费一级毛片不卡不收费| 亚洲国产精品成人| 亚洲一区二区三区影院| 亚洲va久久久噜噜噜久久|