首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Acegi Security 系列第 4 部分:保護 JSF 應用程序的完整配置與協作機制

     編輯:Java 相關知識

核心原則:Acegi 負責安全,JSF 負責展示

常見誤區以為需在 JSF 中編寫登錄頁面邏輯。正確模式:Acegi 自動提供登錄頁面、會話管理、記住我功能;JSF 專注於業務組件渲染。兩者通過 web.xml 統一部署,無需編寫任何 Java 安全代碼。

web.xml 完整配置解析

<web-app>
  <!-- 1. 上下文參數 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/acegi-config.xml</param-value>
  </context-param>
  
  <context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
  </context-param>
  
  <context-param>
    <param-name>javax.faces.CONFIG_FILES</param-name>
    <param-value>/WEB-INF/faces-config.xml</param-value>
  </context-param>

  <!-- 2. 監聽器:啟動 Spring 與 JSF -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>com.sun.faces.config.ConfigureListener</listener-class>
  </listener>

  <!-- 3. Faces Servlet -->
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>

  <!-- 4. Acegi Filter Chain Proxy -->
  <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>
</web-app>

關鍵組件說明

組件角色
ContextLoaderListener啟動 Spring IOC 容器,載入 acegi-config.xml 定義的所有 Bean(過濾器、管理器、提供者)
ConfigureListenerJSF 初始化監聽器,處理 ServletContext/Request/Session/Attribute 事件
FilterToBeanProxy橋接 Servlet Filter 與 Spring Bean,委派給 FilterChainProxy 執行完整過濾器鏈
/* 映射所有請求經過 Acegi 過濾器鏈,JSF 頁面 (.faces) 自然受保護

啟動階段事件序列

  1. Servlet 容器創建 ServletContext
  2. 實例化並註冊所有 <listener>
  3. ContextLoaderListener.contextInitialized() → 解析 Acegi 配置,創建 WebApplicationContext,實例化所有安全 Bean
  4. ConfigureListener.contextInitialized() → 校驗 JSF 托管 Bean 類是否存在
  5. 容器實例化 FilterToBeanProxy,註冊為過濾器
  6. 容器實例化 FacesServlet,開始監聽 *.faces 請求

請求處理階段事件序列

  1. 容器創建 ServletRequest、ServletResponse
  2. ConfigureListener.requestInitialized() → 準備 FacesContext(新會話則創建)
  3. 容器檢查會話狀態(Cookie/URL Rewriting),恢復或創建 HttpSession
  4. URL 匹配 /* → 調用 FilterToBeanProxy.doFilter()
  5. Acegi 過濾器鏈執行:
    • 檢查 Session 中認證信息
    • 未認證 → 顯示登錄頁面(Acegi 內建)
    • 已認證 → 執行授權決策(FilterSecurityInterceptor)
  6. 授權通過 → 更新 ServletContext 認證屬性
  7. ConfigureListener.attributeReplaced() → 同步 FacesContext(無 JSF Bean 變更則無操作)
  8. 控制權轉給 FacesServlet → 執行 JSF 生命周期 → 響應

關鍵協作細節

  • 登錄頁面由 Acegi 提供:ExceptionTranslationFilter 配置 authenticationEntryPoint 指向登錄頁,無需 JSF 介入
  • 會話共享:Acegi 將 Authentication 存入 HTTP Session,JSF 可通過 ExternalContext.getSessionMap() 訪問
  • 無縫重定向:登錄成功後 Acegi 自動重定向到原請求的 JSF 頁面(defaultTargetUrl / filterProcessesUrl 機制)

示例應用部署

  1. WAR 複製到 Tomcat webapps
  2. 下載 JSF 1.1 (jsf-1_1_01.zip) → JAR 放入 WEB-INF/lib
  3. 啟動 Tomcat,訪問 https://localhost:8080/JSFAcegiSample
  4. 體驗:索引頁 → 受保護資源鏈接 → Acegi 登錄頁 → 登錄後自動跳轉回目標 JSF 頁面

總結

本文確立了 web.xml 為核心的聲明式整合模式:Spring ContextLoaderListener 載入安全上下文,Acegi FilterToBeanProxy 攔截所有請求,JSF ConfigureListener 管理組件生命周期。兩大框架通過 Servlet 標準接口(Listener/Filter/Servlet)協作,實現「安全與展示關注點完全分離」。下一部分將深入 Bean 級安全保護。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved