在Acegi(八) 和Acegi(九) 裡, 我們對securityContextHolderAwareRequestFilter有了個較為全面的剖析.在這篇做個小結, 也把一些漏落補上.
在上兩篇裡,我們實際上是介紹了三個類: SecurityContextHolderAwareRequestFilter、 SecurityContextHolderAwareRequestWrapper和SavedRequestAwareWrapper(及由些想到的 SavedRequest). 現在我們回過頭再看時,對它們之間也有了個更清醒的了認識: Acegi通過這個SecurityContextHolderAwareRequestFilter把Request給Wrap下, 而這個wrapper就是SecurityContextHolderAwareRequestWrapper或 SavedRequestAwareWrapper. SavedRequestAwareWrapper繼承自SecurityContextHolderAwareRequestWrapper類.
我們再看在Acegi(八)配置,
Xml代碼
<bean id="securityContextHolderAwareRequestFilter"
class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />
通過這個配置, securityContextHolderAwareRequestFilter實際上用SavedRequestAwareWrapper來包裝Acegi攔截下來的Request. 這是怎麼回事? 配置中沒體現出來呀. 看源碼,發現原來SavedRequestAwareWrapper是通過" Class wrapperClass = SavedRequestAwareWrapper.class; "這個屬性寫死的. 這樣默認情況下, securityContextHolderAwareRequestFilter就可以直接用了. 那怎麼換呢? 有一個方法setWrapperClass,通過它可以替換究竟用哪個wrapper了. (這裡又有一個問題了, 在Spring的配置文件中,用property標簽設置 wrapperClass時,value裡應該是一個String類型的,那怎麼轉成Class類型的呢? ).
再看 securityContextHolderAwareRequestFilter類的文檔, 發現,我們可以來自己的實現類來設置wrapperClass. 那自已定制的類又有什麼特殊的要求呢?有, 自己定制的類就是要有一個公共的構造方法, 這個公共方法得接受兩個參數: HttpServletRequest和 PortResolver. 當然定制的類是要繼承 HttpServletRequestWrapper類 或實現 HttpServletRequest接口.
-------------------------------
至此, 對 securityContextHolderAwareRequestFilter介紹告一段落了. 下面說下在此過程中發現的一個Filter,即HttpRequestIntegrationFilter. 看名字好像能看出點什麼來, 文檔介紹是這樣的:"Populates SecurityContext with the Authentication obtained from the container's HttpServletRequest.getUserPrincipal()". 也就是說通過這個filter把Web(或應用服務器)容器裡傳來的Security信息傳給Acegi放到 SecurityContext中.
通過這個Filter, Acegi可以跟Java裡的標准JAAS結合,或像Tomcat自身的Security管理信息? 還沒見過, 以後留意.