科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件第一個Acegi程式 - 設定文件

第一個Acegi程式 - 設定文件

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文是有关如何完成第一個Acegi程式 - 設定文件。

作者:良葛格 来源:CSDN 2008年2月17日

关键字: 設定文件 Acegi Linux

  • 评论
  • 分享微博
  • 分享邮件
首先請先至Acegi官方網站,下載Acegi程式庫,在撰寫這份教學文件之時,所使用的版本是1.0.3。

Acegi相關類別之間的依賴關係,可以藉由IoC容器來協助建立,在這邊您可以使用 Spring 的IoC容器功能,您可以在下載的Acegi檔案中,找到acegi-security-sample-tutorial.war,將之使用解壓縮軟體解 開,可以在WEB-INF\lib下,找到所需的Spring程式庫,在Acegi 1.0.3中的acegi-security-sample-tutorial.war所搭配的是Spring 1.2.8。

要完成您第一個Acegi程式,您需要以下的程式庫:
  • acegi-security-1.0.3.jar
  • spring-1.2.8.jar

為了在Web應用程式中,使用Acegi搭配Spring的Context資訊,來完成Acegi的依賴關係配置,您要在web.xml中設定 org.springframework.web.context.ContextLoaderListener,並在Context參數中,指定設定檔 案位置與名稱,而Acegi主要透過Filter Chain來達到請求的檢查、驗證、授權、登出等動作,您可以在web.xml中如下設定:
  • web.xml
<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

<display-name>Acegi 範例</display-name>

<!-- 指定Acegi資訊的設定檔-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/acegi-config.xml</param-value>
</context-param>

<!-- Acegi 的 Filter Chain 代理 -->
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>
org.acegisecurity.util.FilterToBeanProxy
</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>
org.acegisecurity.util.FilterChainProxy
</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 取得Spring的Context -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>

org.acegisecurity.util.FilterToBeanProxy建立 org.acegisecurity.util.FilterChainProxy實例,並將請求轉交給FilterChainProxy來處理,接下來 就是配置acegi-config.xml的內容,在這邊先假設一個需求情境,您想要對Web應用程式中的/protected/下所有資源進行保護,如 果使用者試圖存取/protected/下的資源,就先將其送至/acegilogin.jsp進行登入,登入成功後顯示使用者所請求的資源,使用者也可 以直接連接/acegilogin.jsp,登入成功後,預設顯示/loginsuccess.jsp,您可以在acegi-config.xml中加入 以下的設定:
<!-- 驗證處理,使用表單 -->
    <bean id="authenticationProcessingFilter"
          class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"> 

        <!-- 驗證管理員,處理驗證資訊提供者  -->
        <property name="authenticationManager" ref="authenticationManager"/> 
        <!-- 驗證失敗URL -->
        <property name="authenticationFailureUrl" value="/acegilogin.jsp"/> 
        <!-- 驗證成功預設URL -->
        <property name="defaultTargetUrl" value="/protected/userinfo.jsp"/> 
        <!-- 驗證處理的提交位址 -->
        <property name="filterProcessesUrl" value="/j_acegi_security_check"/> 
    </bean>        

可以看到在這邊使用了AuthenticationProcessingFilter來處理驗證,實際對使用者的驗證是交給驗證管理員,也就是authenticationManager屬性中所設定的實例,可以在acegi-config.xml中加入:
    <!-- 驗證管理員,管理驗證資訊提供者 -->
   <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager"> 
      <property name="providers"><!-- 可有多個提供者,其中一個驗證通過即可以了 --> 
         <list> 
            <ref local="daoAuthenticationProvider"/> 
         </list> 
      </property> 
   </bean>


驗證管理員管理驗證提供者,也就是實際提供使用者名稱、密碼、角色資訊的物件,來源可以是資料庫或設定文件中的訊息,基於來源的不同,您可以使用 org.acegisecurity.providers.dao.DaoAuthenticationProvider,並指定其 userDetailsService屬性,設定驗證訊息來源:
   <!-- 驗證提供者,指定使用記憶體來源中的驗證資訊 -->
   <bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider"> 
        <property name="userDetailsService" ref="inMemoryDaoImpl"/>
   </bean> 
    
   <bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
        <property name="userMap">   
            <value>   
                caterpillar=123456,ROLE_SUPERVISOR
                user1=user1pwd,ROLE_USER
                user2=user2pwd,disabled,ROLE_USER    
            </value>   
        </property>   
    </bean> 

在這邊使用userMap屬性指定可以登入的使用者名稱、密碼、是否啟用、角色等資訊。

當驗證失敗會發生例外,這時需要將之送至/acegilogin.jsp,權限不符而試圖取得資源時則將之送至/accessDenied.jsp,這可以使用org.acegisecurity.ui.ExceptionTranslationFilter來達到:
    <!-- 發生驗證錯誤或權限錯誤時的處理 -->
    <bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter"> 
        <property name="authenticationEntryPoint"> 
            <bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint"> 
                <property name="loginFormUrl" value="/acegilogin.jsp"/> 
                <property name="forceHttps" value="false"/> 
            </bean> 
        </property> 
        <property name="accessDeniedHandler"> 
            <bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl"> 
                <property name="errorPage" value="/accessDenied.jsp"/> 
            </bean> 
        </property> 
    </bean>      

接下來要定義可以存取的資源,由於在這邊是針對URL進行規範,可以使用org.acegisecurity.intercept.web.FilterSecurityInterceptor:
    <!-- FilterSecurityInterceptor 對 URI 進行保護 -->
    <bean id="filterSecurityInterceptor"
          class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
        <!-- 驗證管理員 -->
        <property name="authenticationManager" ref="authenticationManager" />
        <!-- 授權管理員 -->
        <property name="accessDecisionManager" ref="accessDecisionManager" />
        <property name="objectDefinitionSource">
            <value>
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
                PATTERN_TYPE_APACHE_ANT
                /protected/**=ROLE_SUPERVISOR,ROLE_USER
            </value>
        </property>
    </bean>

FilterSecurityInteceprot需要參考至驗證管理員取得驗證訊息,以對使用者進行驗證,而是否授權則必須以投票的方式來決定,Acegi的解決方案有幾種:
  1. 如果有一個同意就通過
  2. 如果都同意就通過
  3. 如果都不反對就通過

例如若希望/protected/下可以被使用者(USER)或管理者(SUPERVISOR)存取,採第一個方案的話則使用AffirmativeBased實作:
    <!-- 授權管理員 -->
    <bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
         <!-- 是否全部棄權時視為通過 -->
         <property name="allowIfAllAbstainDecisions" value="false" />
         <property name="decisionVoters">
             <list>
                 <bean class="org.acegisecurity.vote.RoleVoter" />
             </list>
         </property>
    </bean>

RoleVoter對使用者群組中,有ROLE_作為前置文件的進投票,您也可以在設定RoleVoter實例時,使用其rolePrefix來改變前置文字。

在所有的Filter被呼叫之前,通常會有個HttpSessionContextIntegrationFilter,它會建立Security Context物件,後續的Filter會將安全相關訊息儲存於其中,也可以取得當中的安全相關訊息:
<bean id="httpSessionContextIntegrationFilter"
        class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />

Acegi是基於Filter Chain來完成請求的檢查、驗證、授權等動作,所以要將以上的Filter串在一起了:
    <!-- Filter Chain -->
     <bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">  
       <property name="filterInvocationDefinitionSource">  
          <value>  
            CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 
            PATTERN_TYPE_APACHE_ANT 
            /**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
                 exceptionTranslationFilter,filterSecurityInterceptor

         </value> 
      </property> 
    </bean>

所完成的acegi-config.xml完整檔案如下所示:
  • acegi-config.xml
<?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="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
<!-- 驗證管理員,處理驗證資訊提供者 -->
<property name="authenticationManager" ref="authenticationManager"/>
<!-- 驗證失敗URL -->
<property name="authenticationFailureUrl" value="/acegilogin.jsp"/>
<!-- 驗證成功預設URL -->
<property name="defaultTargetUrl" value="/protected/userinfo.jsp"/>
<!-- 驗證處理的提交位址 -->
<property name="filterProcessesUrl" value="/j_acegi_security_check"/>
</bean>

<!-- 驗證管理員,管理驗證資訊提供者 -->
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers"><!-- 可有多個提供者,其中一個驗證通過即可以了 -->
<list>
<ref local="daoAuthenticationProvider"/>
</list>
</property>
</bean>

<!-- 驗證提供者,指定使用記憶體來源中的驗證資訊 -->
<bean id="daoAuthenticationProvider" class="org.acegisecurity.providers.dao.DaoAuthenticationProvider">
<property name="userDetailsService" ref="inMemoryDaoImpl"/>
</bean>

<bean id="inMemoryDaoImpl" class="org.acegisecurity.userdetails.memory.InMemoryDaoImpl">
<property name="userMap">
<value>
caterpillar=123456,ROLE_SUPERVISOR
user1=user1pwd,ROLE_USER
user2=user2pwd,disabled,ROLE_USER
</value>
</property>
</bean>

<!-- 發生驗證錯誤或權限錯誤時的處理 -->
<bean id="exceptionTranslationFilter" class="org.acegisecurity.ui.ExceptionTranslationFilter">
<property name="authenticationEntryPoint">
<bean class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilterEntryPoint">
<property name="loginFormUrl" value="/acegilogin.jsp"/>
<property name="forceHttps" value="false"/>
</bean>
</property>
<property name="accessDeniedHandler">
<bean class="org.acegisecurity.ui.AccessDeniedHandlerImpl">
<property name="errorPage" value="/accessDenied.jsp"/>
</bean>
</property>
</bean>

<!-- FilterSecurityInterceptor 對 URI 進行保護 -->
<bean id="filterSecurityInterceptor"
class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
<!-- 驗證管理員 -->
<property name="authenticationManager" ref="authenticationManager" />
<!-- 授權管理員 -->
<property name="accessDecisionManager" ref="accessDecisionManager" />
<property name="objectDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/protected/**=ROLE_SUPERVISOR,ROLE_USER
</value>
</property>
</bean>

<!-- 授權管理員 -->
<bean id="accessDecisionManager" class="org.acegisecurity.vote.AffirmativeBased">
<!-- 是否全部棄權時視為通過 -->
<property name="allowIfAllAbstainDecisions" value="false" />
<property name="decisionVoters">
<list>
<bean class="org.acegisecurity.vote.RoleVoter" />
</list>
</property>
</bean>

<bean id="httpSessionContextIntegrationFilter"
class="org.acegisecurity.context.HttpSessionContextIntegrationFilter" />
 
<!-- Filter Chain -->
<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/**=httpSessionContextIntegrationFilter,authenticationProcessingFilter,
exceptionTranslationFilter,filterSecurityInterceptor
</value>
</property>
</bean>
</beans>

查看本文来源
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章