本文以一個可直接在 Eclipse 3.4 運行的最小化 Web 專案為例,逐層剖析 web.xml 與 applicationContext-acegi-security.xml 的關鍵配置點。
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext-acegi-security.xml</param-value>
</context-param>
<filter>
<filter-name>Acegi Filter</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</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
關鍵點:
FilterToBeanProxy:標準 Servlet Filter,啟動時從 Spring 容器取得 FilterChainProxy 實例,將所有請求委派給它。targetClass:指定代理的 Bean 類別,極少需修改。ContextLoaderListener:啟動 Spring 根容器,載入 Acegi 配置檔。<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/login.jsp=#NONE#
/**=httpSessionContextIntegrationFilter,
authenticationProcessingFilter,
exceptionTranslationFilter,
filterInvocationInterceptor
</value>
</property>
</bean>
filterInvocationDefinitionSource 字串由 Spring PropertyEditor 自動轉為 FilterInvocationDefinitionSource 介面實現 (通常為 PathBasedFilterInvocationDefinitionMap)。
| Bean ID | 類別 | 職責 |
|---|---|---|
| httpSessionContextIntegrationFilter | HttpSessionContextIntegrationFilter | Session ↔ SecurityContext 同步 |
| authenticationProcessingFilter | AuthenticationProcessingFilter | 處理登入表單驗證 |
| exceptionTranslationFilter | ExceptionTranslationFilter | 捕獲安全異常,轉為 HTTP 回應 |
| filterInvocationInterceptor | FilterSecurityInterceptor | URL 權限決策 |
後續文章將詳細說明每個 Filter 內部如何調用「七劍」完成具體邏輯。