進行中  
          。。。
          日歷
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789
          統計
          • 隨筆 - 13
          • 文章 - 1
          • 評論 - 3
          • 引用 - 0

          導航

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章檔案

          相冊

          link

          搜索

          •  

          最新隨筆

          最新評論

          閱讀排行榜

          評論排行榜

           
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          作者:一餐三碗
          對于任何一個完整的應用系統,完善的認證和授權機制是必不可少的。在基于SpringFramework的WEB應用中,
          我們可以使用Acegi作為安全架構的實現。本文將介紹如何在基于Spring構架的Web應用中使用Acegi,并且詳細介
          紹如何配置和擴展Acegi框架以適應實際需要。
          1. 概述
          Acegi是一個專門為SpringFramework應用提供安全機制的開放源代碼項目,全稱為Acegi Security System for Spring,當前版本為
          0.8.3。它使用了Spring的方式提供了安全和認證安全服務,包括使用Bean Context,攔截器和面向接口的編程方式。通過精心
          配置Acegi安全系統能夠輕松地適用于復雜的安全需求。它既能應用于WEB應用也能應用于非WEB應用。在 本文的示例程序
          里,我將演示如何將Acegi應用于WEB應用程序。通過這個例子詳細介紹如何配置Acegi的各個組件,同時介紹如何擴展Acegi
          使其能夠從數據庫中讀取配置信息。
          2. 例子說明
          本文的例子是一個聯系人管理程序,使用SpringFramework 1.2.4 和 Acegi0.8.3,數據庫采用Mysql。程序的目錄結構如下:  
          acegi-sample
          │ contactadd.jsp//增加聯系人頁面
          │ contactedit.jsp//編輯聯系人頁面
          │ contactlist.jsp//聯系人列表頁面
          │ contactmainterance.jsp//聯系人操作頁面
          │ index.jsp//主頁面
          │ login.jsp//登錄頁面
          │ logoff.jsp//登出頁面

          ├─WEB-INF
          │ │ web.xml
          │ │ applicationContext-basic.xml
          │ │ applicationContext-security-acegi.xml
          │ │ log4j.properties
          │ │
          │ ├─src
          │ │ └─sample//java代碼目錄
          │ ├─classes
          │ └─lib//依賴包目錄
          └─db//建表腳本目錄
          程序的ER圖如下:
          file:///I|/doc/index.htm (1 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          說明:authorities用來存放用戶權限配置信息,其中,AUTHORITY字段存放以“AUTH_”開頭的權限標志串。AUTH_TYPE
          存放權限類型。PROTECTED_RES字段存放受保護的資源字符串。DISPLAY字段存放權限顯示名稱。userinfo用來存放用戶信
          息。authorities和userinfo是多對多關聯,使用user_auth作為關聯表。contacts存放用戶信息。 在這個例子中,為了使程序簡單明
          了,我們沒有引入一般情況下會有的用戶組或者角色的概念,不過在后面的內容里我們將看到對現有的安全模型進行擴展是
          一件很容易的事。
          程序的靜態類圖如下:
          3.配置文件說明
          接下來,我們將進入本文的重要內容,開始對Acegi應用程序所牽涉到的配置文件進行一一說明。
          3.1 web.xml
          首先聲明SpringFramework的配置文件列表。為了便于管理,將業務方法相關的配置文件和Acegi安全配置相關的配置文件分
          開。  
          file:///I|/doc/index.htm (2 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>
          /WEB-INF/applicationContext-basic.xml
          /WEB-INF/applicationContext-security-acegi.xml
          </param-value>
          </context-param>
          其次聲明Acegi過濾器。  
          <!--Acegi Filter Chain Proxy -->
          <filter>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
          <init-param>
          <param-name>targetClass</param-name>
          <param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>
          </init-param>
          </filter>
          <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
          說明:Acegi對WEB應用的支持主要是依靠servlet 過濾器(filter) 來實現的。每一個http request都將被這些過濾器層層攔截 并
          進行安全處理(包括認證和授權)。針對不同的安全處理,Acegi提供了不同的過濾器。過濾器的配置信息位于web.xml,但是
          我們又希望把Acegi的過濾器配置信息放在SpringFramework的配置文件里(applicationContext-security-acegi.xml),從而實現對
          這些過濾器的“控制反轉”。解決這個問題的方法是采用Acegi提供的FilterToBeanProxy。FilterToBeanProxy顧名思義就是對
          Acegi過濾器Bean的代理,它的主要功能就是將http請求依次分派給對應的過濾器Bean。
          3.2 applicationContext-security-acegi.xml
          applicationContext-security-acegi.xml主要包括認證相關配置信息和WEB資源授權配置信息。首先是聲明過濾器序列。  
          <bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
          <property name="filterInvocationDefinitionSource">
          <value>
          CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
          PATTERN_TYPE_APACHE_ANT
          /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
          </value>
          </property>
          </bean>
          各個過濾器的作用如下:
          httpSessionContextIntegrationFilter
          根據session中存放的信息組裝ContextHolder。ContextHolder主要用于存放SecureContext,
          包括用戶的權限信息
          authenticationProcessingFilter 處理認證請求(通常是一個登錄頁面的表單請求)
          file:///I|/doc/index.htm (3 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          anonymousProcessingFilter
          匿名用戶處理。如果用戶尚未登錄,將生成一個匿名用戶的Authentication存放到
          ContextHolder中
          securityEnforcementFilter 強制安全驗證過濾器。驗證所請求的url是否在用戶的權限范圍內。
          3.2.1 httpSessionContextIntegrationFilter相關配置信息
           
          <bean id="httpSessionContextIntegrationFilter" class="net.sf.acegisecurity.context.HttpSessionContextIntegrationFilter">
          <property name="context"><value>net.sf.acegisecurity.context.security.SecureContextImpl</value></property>
          </bean>
          說明: context屬性指定context的實現類。
          3.2.2 authenticationProcessingFilter相關配置信息
          authenticationProcessingFilter的配置比較復雜,我們通過下圖來看一下:
          authenticationProcessingFilter配置說明:
          file:///I|/doc/index.htm (4 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          authenticationManager 認證管理器
          authenticationFailureUrl 認證失敗后,重定向的url
          defaultTargetUrl 認證成功后,重定向的url
          filterProcessesUrl
          該過濾器攔截的url,通常是/j_acegi_security_check,和登錄頁面(login.jsp)的登錄表單的action相

          authenticationManager(認證管理器)用于管理AuthenticationProvider(認證提供者)。它的作用是使你能夠通過多個不同的認
          證管理源來對用戶進行認證。認證管理器將依次調用認證提供者的認證方法,直到認證通過。本程序使用兩種認證提供者。
          authenticationManager配置說明:
          daoAuthenticationProvider 基于數據庫的認證提供者。
          anonymousAuthenticationProvider 用于認證匿名用戶。
          daoAuthenticationProvider主要功能是從數據庫取出用戶名和密碼,判斷登錄信息是否正確,如果是,則取出用戶權限等用戶
          信息,并且存放到cache中,以便以后再次使用。具體流程可以參考:DaoAuthenticationProvider的authenticate方法。
          daoAuthenticationProvider配置說明:
          authenticationDao 認證數據訪問對象,用于獲取用戶信息,包括:用戶名,用戶密碼,用戶狀態和用戶權限。
          userCache 用戶信息cache實現bean
          jdbcDaoImpl是認證數據訪問對象,它能夠從默認的數據庫結構中獲取用戶信息,由于Acegi默認的數據庫結構和本程序的不
          同,因此需要修改jdbcDaoImpl的默認sql。注意,采用這種方式能夠使Acegi很好的兼容舊的應用程序,因為它對底層的數據結
          構并沒有強制要求。jdbcDaoImpl配置說明:
          dataSource 數據源bean
          usersByUsernameQuery 用戶信息查詢sql
          authoritiesByUsernameQuery 用戶權限查詢sql
          userCache用于定義用戶信息cache功能的提供者。userCache配置說明:
          cache 定義ehcache工廠bean
          本程序采用ehcache作為cache實現。由于認證管理器在每次對http請求進行認證之前都會查找用戶信息,通過使用cache就可以
          避免每次都重復訪問數據庫。
          3.2.3 anonymousProcessingFilter相關配置信息:
           
          <bean id="anonymousProcessingFilter" class="net.sf.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
          <property name="key"><value>foobar</value></property>
          <property name="userAttribute"><value>anonymousUser,AUTH_ANONYMOUS</value></property>
          </bean>
          說明:anonymousProcessingFilter的作用是判斷ContextHolder中是否有Authentication對象,如果沒有就創建一個Authentication對
          象,其中包含的用戶名是anonymousUser,用戶權限是AUTH_ANONYMOUS。這使得沒有登錄的匿名用戶能夠自動的獲得匿
          名的用戶名和權限。
          3.2.4 securityEnforcementFilter相關配置信息
          file:///I|/doc/index.htm (5 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          securityEnforcementFilter的配置比較復雜,我們通過下圖來看一下:
          securityEnforcementFilter配置說明:
          filterSecurityInterceptor 實現對URL資源進行授權訪問。
          authenticationEntryPoint 配置登錄界面信息。
          securityEnforcementFilter的作用主要是將http請求轉發給filterSecurityInterceptor,由filterSecurityInterceptor來對HTTP請求的合法
          性進行判斷。
          filterInvocationInterceptor配置說明:
          authenticationManager 認證管理器
          accessDecisionManager 投票通過策略管理器
          objectDefinitionSource
          URL的權限配置信息。用于指定不同的URL資源對應的權限。配置如下:
          /**/*.jpg=AUTH_ANONYMOUS,AUTH_USER
          /**/*.gif=AUTH_ANONYMOUS,AUTH_USER
          /**/*.png=AUTH_ANONYMOUS,AUTH_USER
          /login.jsp*=AUTH_ANONYMOUS,AUTH_USER
          /**=AUTH_USER
          以上配置指定AUTH_ANONYMOUS權限的用戶(即匿名用戶)只可以訪問圖片資源和登錄頁
          面,AUTH_USER權限的用戶可以訪問全部WEB資源。
          accessDecisionManager(訪問決策管理器)首先通過authenticationManager判斷用戶是否通過認證(即是否已經登錄),然后根
          據objectDefinitionSource的配置信息調用accessDecisionManager對用戶權限進行投票。
          httpRequestAccessDecisionManager配置說明:
          allowIfAllAbstainDecisions 設定是否允許:“沒人反對就通過”的投票策略
          decisionVoters 投票者
          file:///I|/doc/index.htm (6 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          httpRequestAccessDecisionManager(投票通過策略管理器)用于管理投票通過策略。Acegi提供三種投票通過策略的實現:
          AffirmativeBased(至少一個投票者同意方可通過),ConsensusBased(多數投票者同意方可通過),UnanimousBased(所有投
          票者同意方可通過)。本程序采用AffirmativeBased策略,并且禁止“沒人反對就通過”的投票策略。
          roleVoter配置說明:
          rolePrefix
          該投票者支持的權限前綴,默認是“ROLE_”,本程序所有的權限字符串均以“AUTH_”開頭,
          故設為“AUTH_”
          通過設定rolePrefix可以指定roleVoter所支持的權限范圍。
          3.3 applicationContext-basic.xml
          applicationContext-basic.xml主要包括數據訪問對象,業務方法,業務方法安全管理攔截器的配置信息。先看一下總攬圖:
          我將主要講解業務方法安全管理攔截器(MethodSecurityInterceptor)的相關配置,其它的配置就不再贅述了,請參考相關文
          檔。
          3.3.1 contactManager相關配置信息
           
          file:///I|/doc/index.htm (7 of 10)2005-12-6 10:37:51
          實戰基于Spring框架的WEB應用的安全框架
          <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>
          /WEB-INF/applicationContext-basic.xml
          /WEB-INF/applicationContext-security-acegi.xml
          </param-value>
          </context-param>
          其次聲明Acegi過濾器。  
          <!--Acegi Filter Chain Proxy -->
          <filter>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
          <init-param>
          <param-name>targetClass</param-name>
          <param-value>net.sf.acegisecurity.util.FilterChainProxy</param-value>
          </init-param>
          </filter>
          <filter-mapping>
          <filter-name>Acegi Filter Chain Proxy</filter-name>
          <url-pattern>/*</url-pattern>
          </filter-mapping>
          說明:Acegi對WEB應用的支持主要是依靠servlet 過濾器(filter) 來實現的。每一個http request都將被這些過濾器層層攔截 并
          進行安全處理(包括認證和授權)。針對不同的安全處理,Acegi提供了不同的過濾器。過濾器的配置信息位于web.xml,但是
          我們又希望把Acegi的過濾器配置信息放在SpringFramework的配置文件里(applicationContext-security-acegi.xml),從而實現對
          這些過濾器的“控制反轉”。解決這個問題的方法是采用Acegi提供的FilterToBeanProxy。FilterToBeanProxy顧名思義就是對
          Acegi過濾器Bean的代理,它的主要功能就是將http請求依次分派給對應的過濾器Bean。
          3.2 applicationContext-security-acegi.xml
          applicationContext-security-acegi.xml主要包括認證相關配置信息和WEB資源授權配置信息。首先是聲明過濾器序列。  
          <bean id="filterChainProxy" class="net.sf.acegisecurity.util.FilterChainProxy">
          <property name="filterInvocationDefinitionSource">
          <value>
          CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
          PATTERN_TYPE_APACHE_ANT
          /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter
          </value>
          </property>
          </bean>
          各個過濾器的作用如下:
          httpSessionContextIntegrationFilter
          根據session中存放的信息組裝ContextHolder。ContextHolder主要用于存放SecureContext,
          包括用戶的權限信息
          authenticationProcessingFilter 處理認證請 通常
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          4.程序演示
          首先,配置兩個用戶:root,readonly。具有的權限如下圖:
          登錄界面:
          以readonly用戶登錄后,執行刪除聯系人操作,顯示操作被拒絕:
          file:///I|/doc/index.htm (9 of 10)2005-12-6 10:37:51
          實戰Acegi:使用Acegi作為基于Spring框架的WEB應用的安全框架
          5.總結
          在本文的示例程序中我們只對業務對象(ContactManager)進行安全保護,對業務領域對象(Contact)的訪問并沒有作限
          制,這是由于在Acegi框架中采用ACL(訪問控制列表)技術實現這個功能,這使得一旦我們的業務領域對象數量很多的話,
          效率將變得很低,因此我們將對業務領域對象訪問控制的代碼放在業務對象的業務方法中。
          將業務無關的代碼從業務代碼中剝離,使業務代碼更干凈,系統結構更合理是每個開發人員的夢想。隨著AOP技術的日漸流
          行和日益發展,這個夢想已經離我們不遠了。本文中的例子通過結合使用SpringFramework和Acegi兩種開源框架,實現了將安
          全認證和授權代碼和事務代碼從業務代碼中分離。
          6.代碼說明
          本文相關代碼acegi-sample.war.
          Mysql的建表腳本在db目錄下.
          為了減小體積,已經將WEB-INF\lib下的依賴包刪除,請自行下載以下包,并拷貝至WEB-INF\lib下:
          spring-1.2.4.jar
          acegi-security-0.8.3.jar
          aopalliance-1.0.jar
          c3p0-0.9.0.jar
          commons-logging-1.0.4.jar
          ehcache-1.1.jar
          log4j-1.2.8.jar
          mysql-connector-java-3.1.10-bin.jar
          oro-2.0.8.jar
          7.參考資料
          ● Acegi Security System for Spring Reference Documentation。
          ● Acegi Security System contacts sample。本文中的示例程序參考了Acegi的contacts演示程序。
          關于作者
          一餐三碗 系統架構師 從事電信行業軟件開發多年,目前專注于網管軟件的開發。
           
          file:///I|/doc/index.htm (10 of 10)2005-12-6 10:37:51
          posted on 2006-08-17 16:19 kongjia 閱讀(508) 評論(0)  編輯  收藏

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


          網站導航:
           
           
          Copyright © kongjia Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 桂平市| 宜春市| 娱乐| 秭归县| 科技| 杭锦后旗| 大洼县| 建宁县| 呼玛县| 乌海市| 乐陵市| 塘沽区| 灵璧县| 宜宾县| 确山县| 武冈市| 马龙县| 大名县| 巧家县| 内江市| 桂阳县| 新民市| 盖州市| 兴海县| 福贡县| 化州市| 大同县| 中西区| 天峨县| 封丘县| 定襄县| 双桥区| 东港市| 惠安县| 嵩明县| 孟连| 荔浦县| 容城县| 苏尼特右旗| 巴彦淖尔市| 抚宁县|