欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
解析Acegi Security System for Spring

我發(fā)現我給自己設了個(gè)陷阱,對于Acegi Security System的解析并不是光寫(xiě)個(gè)安全認證的流程就能說(shuō)清楚的。雖然看起來(lái)Acegi的文檔確實(shí)挺累,但是當我動(dòng)筆寫(xiě)時(shí)卻發(fā)現要寫(xiě)得比這個(gè)文檔更好還是挺難的。畢竟我們不能讓本來(lái)很難的事情一下子就變得很簡(jiǎn)單了,我也是昨天重要看了一遍了Acegi Security System的源代碼,才發(fā)現我自己有明白了好多不明白的東西。但是我仍然希望我寫(xiě)的東西能夠幫助那些正在學(xué)習和研究Acegi Security System的人們,所以我又開(kāi)始動(dòng)筆了,呵呵!


雖然我不想介紹太多與安全認證流程無(wú)關(guān)的東西,但是有些東西的講解卻是必不可少的,因為沒(méi)有這些基本的概念和類(lèi),后面的東西就沒(méi)法說(shuō)清了。不過(guò)對于具體的類(lèi)、類(lèi)圖和它們之間的關(guān)聯(lián),我還是推薦去看Professional Java Development with the Spring Framework里關(guān)于Acegi的那一章,對于想讀Acegi的源代碼和了解Acegi內部設計的人來(lái)說(shuō),這一章真是太有用了。

 

本來(lái)不想貼這幅類(lèi)圖的,畢竟有盜版的嫌疑,但是發(fā)現有些東西不貼出來(lái)又說(shuō)不清楚。整個(gè)認證功能的核心是Authentication接口,我們只把Authentication想象成一個(gè)包含用戶(hù)基本信息的類(lèi)就行了,它里面放了用戶(hù)名、密碼、這個(gè)用戶(hù)的具體權限有哪些(當然具體的東西是由它的子類(lèi)UsernamePasswordAuthenticationToken實(shí)現的,其它類(lèi)的存放的信息稍有不同,畢竟驗證的方式還是多種多樣的,我這里描述的所有東西Acegi最常用的實(shí)現方式,而不考慮其它的東西,否則只會(huì )分散注意力,看了之后一頭霧水)。Authentication里還包含了一個(gè)GrantedAuthority接口,今天暫且不討論Authorization的問(wèn)題了,畢竟它與驗證的流程是不相關(guān)的,而具體的細節又極復雜。

 

我們通過(guò)AuthenticationManager這個(gè)接口來(lái)驗證這個(gè)Authtication對象的合法性,真正的驗證過(guò)程看上去很懸,其實(shí)最后的實(shí)現無(wú)非是去數據庫搜索一下是否存在這個(gè)用戶(hù),密碼是否匹配(說(shuō)的仍然是最常用的實(shí)現方式,呵呵),只是它設計的時(shí)候對象的關(guān)聯(lián)比較巧妙,類(lèi)圖看熟了就會(huì )覺(jué)得沒(méi)什么,真正查數據庫的那個(gè)類(lèi)是DaoAuthenticationProvider。這個(gè)接口真正巧妙的地方是它執行后返回的結果是一個(gè)Authentication,而不是用一個(gè)布爾值來(lái)表示驗證成功或失敗。Why? 記得當年在JavaEye上有個(gè)討論Exception的貼子,robbin認為用戶(hù)安全認證應該用Checked Exception來(lái)控制流程,更多的人認為密碼錯誤是正常的事件流,返回布爾值更為恰當,這里不討論這兩種觀(guān)點(diǎn)的對錯,畢竟每個(gè)人站的角度不同,具體的情況也不同。

 

但是如果要實(shí)現認證的透明性,我們要用到的卻是unchecked exception,這個(gè)Exception叫做AuthenticationException(如果是authorization會(huì )拋出AccessDeniedException,不過(guò)道理類(lèi)似),這真是奇妙的事,因為Exeception是可以傳遞的,如果在本類(lèi)里面處理不了這個(gè)Exception,我們就會(huì )將這個(gè)Exception拋給調用這個(gè)類(lèi)的類(lèi),如此循環(huán),直到有一個(gè)類(lèi)可以處理它為止(對于Web來(lái)說(shuō)應該是在頁(yè)面上提示登錄出錯信息)。沒(méi)想到Exception的這個(gè)種特性用在安全認證里如此的合適,權限不夠?用戶(hù)密碼不對?我才不管呢,只要拋出個(gè)異常,最后會(huì )有人把它接住處理掉的。當然這里的另一個(gè)條件是Unchecked,只有unchecked才不會(huì )導致接口的污染,才能達到完全的透明性。

 

有了前面的基礎接口,我們要提出下一個(gè)問(wèn)題了,這個(gè)Authentication對象應該存放在哪里?幾乎每個(gè)做過(guò)Web應用的人告訴我:HttpSession。Acegi也不例外,雖然還有其它的存放地點(diǎn)(要跟具體的Web容器結合,會(huì )導致不兼容性,一般不提倡用)。但是我們馬上會(huì )問(wèn)下一個(gè)問(wèn)題:我們怎么得到Authentication對象?當然我們可以去HttpSession里去取,但是很多時(shí)候我們在驗證的是與Web層無(wú)關(guān)的(比如要用戶(hù)調用Service層的權限或Domain Object的權限)。我們必須用與Web無(wú)關(guān)的API來(lái)獲取Authentication。這讓我們想起了什么?對,是Webwork,WebworkAction是完全與Web API無(wú)關(guān)的,它的Request里的參數自動(dòng)populate成了Action的屬性,但是我們仍然可以通過(guò)ActionContext來(lái)獲取這些信息。它是怎么做到的?是Threadlocal,因為每個(gè)Web Request都會(huì )使Web容器生成一個(gè)新的線(xiàn)程來(lái)處理它的這個(gè)特性使我們可以將這些Web的數據一股腦塞給Threadlocal。這個(gè)存放Authentication的對象叫做SecurityContext,而把SecurityContext放入Threadloal或取出的則是SecurityContextHolder,下面就是它的類(lèi)圖:

 

講完這些基礎設施,我們就可以看具體的認證流程啦,真正的認證是一串的Filter(對Servlet容器熟悉的人應該都不要解釋了)。只不過(guò)Acegi在這些Filter上稍微玩的點(diǎn)花招,因為一般的Filter是不能定義在SpringApplicationContext里的,所以這用了一個(gè)代理的Filter對象FilterToBeanProxyFilter操作Delegate給定義在ApplicationContext里的Filter。這個(gè)似乎跟主題無(wú)關(guān),不過(guò)如果以后真有類(lèi)似的需求的話(huà),這倒是蠻管用的一招。當然還有FilterChainProxy,它把一串的Filter全部定義在一個(gè)bean里,使配置簡(jiǎn)化了好多,呵呵。

 

我們來(lái)看看Filter的一頭一尾。頭是httpSessionContextIntegrationFilter,其實(shí)它的功能前面已經(jīng)討論過(guò)了,在執行前把HttpSession里的Authentication取出來(lái)放到SessionContextHolderThreadlocal)里,在執行完畢后,把Authentication塞回到HttpSession。真正的實(shí)現代碼有一堆,不過(guò)核心的代碼無(wú)非就這么幾行:

Object contextFromSessionObject = httpSession.getAttribute(ACEGI_SECURITY_CONTEXT_KEY);

SecurityContextHolder.setContext((SecurityContext) contextFromSessionObject);

chain.doFilter(request, response);

httpSession.setAttribute(ACEGI_SECURITY_CONTEXT_KEY,,SecurityContextHolder.getContext());

 

Filter的尾是securityEnforcementFilter,它的工作就是進(jìn)真正的用戶(hù)認證的流程控制了,具體的認證工作它會(huì )delegateFilterSecurityInterceptor,但是不管怎么認證,結果無(wú)非是認證成功或失敗,securityEnforcementFilter只要管抓住異常再轉到特定的頁(yè)面就行了。下面就是這個(gè)類(lèi)的信心代碼:

try {

filterSecurityInterceptor.invoke(fi);

}

} catch (AuthenticationException authentication) {

sendStartAuthentication(fi, authentication);

} catch (AccessDeniedException accessDenied) {

sendAccessDeniedError(fi, accessDenied);

}

 

我們再來(lái)看看用戶(hù)登錄是怎么干的吧。Acegi的用戶(hù)登錄很有意思,為了不讓用戶(hù)寫(xiě)任何這方面的代碼,它也直接把這個(gè)功能放到Filter里了,這個(gè)Filter叫做authenticationProcessingFilter。這個(gè)Filter的要求是頁(yè)面上的formAction名字,登錄名、密碼的字段名都是定死的。一個(gè)簡(jiǎn)單的頁(yè)面就這些啦:

<form action="<c:url value=‘ j_acegi_security_check ‘/>" method="POST">

<input type=‘text‘ name=‘j_username‘>

<input type=‘password‘ name=‘j_password‘>

<input name="submit" type="submit">

</form>

記住action必須叫j_acegi_security_check,用戶(hù)名必須叫j_username,密碼必須叫j_password。呵呵,代碼就不寫(xiě)了,無(wú)非就是判斷只要Action名字對,就把用戶(hù)名、密碼取出來(lái)認證一把,最后把認證成功的Authetication對象填到SecurityContextHolder里再導到相應頁(yè)面,認證失敗就導到出錯頁(yè)面。

 

呵呵,好了,認證的核心過(guò)程其實(shí)就這些了,雖然還有其它的好多的Filter和關(guān)聯(lián),但是當我們把核心的內容分析清楚之后,其它的都不難了。(Authorization是例外,有些部分我還沒(méi)看明白)。

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Spring Security,沒(méi)有看起來(lái)那么復雜(附源碼)
spring-security 登陸認證之初次探究
spring security
Acegi安全系統的配置(轉) - Junky‘s IT Notebook - BlogJ...
CAS 與 Spring Security 3.1整合配置詳解
Spring Security(2):過(guò)濾器鏈(filter chain)的介紹
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久