過(guò)頁(yè)頭生成Token,進(jìn)行請(qǐng)求驗(yàn)證,解決Ajax請(qǐng)求安全問(wèn)題。目前為止我做的最多的防止ajax請(qǐng)求攻擊的就是添加驗(yàn)證碼、添加隨機(jī)Token,限制同一請(qǐng)求在規(guī)定時(shí)間內(nèi)的最大請(qǐng)求數(shù)。
下面重點(diǎn)說(shuō)說(shuō)添加隨機(jī)Token限制:
token是為了防止表單重復(fù)提交,token 原理大致為:
1:顯示表單的那個(gè) action 中使用 createToken() 生成一個(gè)隨機(jī)的 token值,并存放在服務(wù)端(session或者cache中),并且傳遞一份到頁(yè)面中
2:表單頁(yè)面使用一個(gè)隱藏表單域獲取后端傳過(guò)來(lái)的 token值,該表單頁(yè)面提交時(shí)會(huì)將此 token 值一同提交到后端
3:在表單頁(yè)面提交到的 actioin 中使用 validateToken() 將服務(wù)端與表單隱藏域中的 token 值進(jìn)行對(duì)比,如果服務(wù)端存在 token值并且與表單提交過(guò)來(lái)的值相等,證明是第一次提交。
4:每次校驗(yàn)過(guò)后服務(wù)端的 token 值會(huì)立即被清除,所以當(dāng)用戶重復(fù)提交時(shí),后面的提交校驗(yàn)都再也無(wú)法通過(guò)。從而實(shí)現(xiàn)了防止重復(fù)提交的功能,validateToken 是在 synchronized 塊中執(zhí)行的保障了多線程下的安全性。
token 會(huì)優(yōu)先存入 me.setTokenCache(ITokenCache) 指定的 TokenCache 中,如果未指定則默認(rèn)使用 session 來(lái)存放
但是這種機(jī)制是有問(wèn)題的,比如我是用ajax提交表單,提交完成以后表單頁(yè)面并不刷新,然后我修改了部分?jǐn)?shù)據(jù)以后再次提交頁(yè)面,那么token還是之前的那個(gè)token,后臺(tái)會(huì)以為這個(gè)為重復(fù)提交不能通過(guò)校驗(yàn),那么請(qǐng)求就不能完成,數(shù)據(jù)無(wú)法得到正確的處理。我認(rèn)為合理的機(jī)制應(yīng)該是這樣的:
1:顯示表單的那個(gè) action 中使用 createToken() 生成一個(gè)隨機(jī)的 token值,并且傳遞一份到頁(yè)面中
2:表單頁(yè)面使用一個(gè)隱藏表單域獲取后端傳過(guò)來(lái)的 token值,該表單頁(yè)面提交時(shí)會(huì)將此 token 值一同提交到后端
3:將提交過(guò)來(lái)的token值放入session或者cache中,然后執(zhí)行controller中的代碼,代碼全部執(zhí)行完以后,再把存入session或cache中的token值刪除掉;驗(yàn)證用戶是否為重復(fù)提交只需要驗(yàn)證提交過(guò)來(lái)的token是否存在于session或cache中,有則為重復(fù)提交,無(wú)則為正常提交。
4:該邏輯應(yīng)該可以寫(xiě)成一個(gè)Interceptor,在需要的地方加上,或者直接設(shè)為全局?jǐn)r截器都是可以的,簡(jiǎn)單,快捷;