前些天通過一個Acegi的Web實例,我們感受了下受保護的好處,也通過一步步的跟蹤,感覺到Acegi裡"七劍"的存在.本來是想著繼續再往下做擴展的,後來一想還是回過頭來整理下研究Acegi過程中的碎得吧,畢竟這樣的碎得寫起輕松些,我也稍稍放松下.
信馬由缰地溜達了下,又想起了當時一開始看Acegi源碼時的如下問題:
1, FilterToBeanProxy --> FilterChainProxy, 一個VirtualFilterChain來模仿Web 容器中的FilterChain, 內容類 (自己寫代碼時也有意識地用protected, private了).
方法的實現與調用 --> 代碼塊的重用.
FilterChainProxy類裡filterInvocationDefinitionSource屬性從String到相應類的自動轉換.
2, Filter調用與方法棧的吻合,畫一個序列圖來表示.
3, SecurityContextHolder的多種實現, 為什麼要有多種實現,每一種實現又有什麼特點?
HttpSession中放沒放SecurityContext? 在SecurityContextHolder裡也有放. 這種有問題了: 如何讓它們倆同步? 刪了一個後又怎樣?
4, 另處一些常用的配置:
logoutFilter, securityContextHolderAwareRequestFilter, anonymousProcessingFilter
出於什麼考慮提出這樣的概念?
5, 這一段的作用:
if (request.getAttribute(FILTER_APPLIED) != null) {
// ensure that filter is only applied once per request
chain.doFilter(request, response);
return;
}
要防止在 filterInvocationDefinitionSource中配置了多個httpSessionContextIntegrationFilter, httpSessionContextIntegrationFilter總是在第一個的. 多配置了也沒用, 若不加有什麼害處不?
6, 為什麼如下這種方式來取HttpSession?
try {
httpSession = request.getSession(forceEagerSessionCreation);
}
catch (IllegalStateException ignored) {
}
若getSesssion時傳一個False會是什麼樣的?一個HttpSession一般什麼時機創建? 現在越來越不考慮這些問題了.
7, 為什麼要把response再包裝下? OnRedirectUpdateSessionResponseWrapper
8, 為什麼每次都要有 SecurityContextHolder.clearContext();這不挺浪費的嗎? 防止Authentication裡的用戶名/密碼/權限在用戶操作時有改? 作為一個通用的安全框架應該支持這個功能的, 把權限控制存放到數據庫中太常見了.
9, 如下代碼段的的注意點:
if (cloneFromHttpSession) {
Assert.isInstanceOf(Cloneable.class, contextFromSessionObject,
"Context must implement Clonable and provide a Object.clone() method");
try {
Method m = contextFromSessionObject.getClass().getMethod("clone", new Class[]{});
if (!m.isAccessible()) {
m.setAccessible(true);
}
contextFromSessionObject = m.invoke(contextFromSessionObject, new Object[]{});
}
catch (Exception ex) {
ReflectionUtils.handleReflectionException(ex);
}
}
9.1 為什麼要 cloneFromHttpSession? 聯想到Hibernate的PersistentContext, 它會自動來做dirty check的, 若不clone一個,直接把一個原來的return給client的話,會影響dirty check的速度.
9.2 自己寫例子試試clone接口的實現與深度拷貝.
10, 從方法 readSecurityContextFromSession看框架級代碼的書寫:
10.1 考慮到多種可能層層設防. 從而確保return一個 non-null,且為實現 SecurityContext接口的HttpSession裡以" ACEGI_SECURITY_CONTEXT_KEY "存放的對象, 不要被"狸貓換太子"了.
10.2, log的書寫.