許可權管理切面攔截控制跳轉頁面
遇到這樣一個問題,先看圖片
系統A與系統B都需要許可權攔截,我這使用到的技術是將攔截許可權的切面這個專案打成jar包供系統A、B使用。
在系統A的controller層使用許可權攔截的註解,當用戶沒有這個許可權的時候跳轉頁面讓他申請當前許可權。
先看切面這個處理:
@Before("annotationPoint()")
public void BeforeAnnotation(JoinPoint joinPoint){
}
切面這個方法返回值為 void ,也就是沒有東西可以返回,那麼我們當處理資訊時發現使用者沒有許可權,我們如何儲存這個缺失的許可權資訊呢?
思考一
一開始我嘗試將這個 void 改成String ,那麼問題來了,這個返回值我在哪裡去獲取呢?我在網上沒有找到合適的答案,沒辦法這個方案只能放棄。
思考二
既然我拿不到這個值,那麼如果我把這個值先存起來,後面再去獲取不就好了?所以我想到了request 的request.setAttribute();
方法在這裡把許可權資訊存起來,然後在去controller層獲取。思路看上去沒什麼問題,但是實際問題來了: 我們知道request的作用域只在當個請求中有效。真是環境是這樣的,整個系統是完全前後端分離的,也就是說我在現在的controller能獲取到這個request中的值,當我處理跳轉頁面,頁面在發非同步請求的時候這個request中的資料就沒了!其次根據開發規範我們的controller也不應該去處理業務邏輯,所以這個方案失敗。
思考三
既然問題是request的作用域問題,那麼我把request換成session不就好了?session的作用域是整個回話內有效。如果這個問題解決。在系統A的環境下測試一切正常。但是問題來了,我在系統B下測試這個session值就獲取不到了,為什麼呢?
我的邏輯處理流程是這樣的:在系統B訪問controller層時並且加了許可權管理的註解,那麼當執行的時候切面會去處理資訊(切面中可以控制重定向),然後統一在重定向到系統A的一個controller去處理。
因為系統A、B是兩個不同埠的專案在執行,他們都有自己的容器,這兩個系統的session肯定不可能共享啊,這個方法依然失敗。
補充一下在切面獲取request和response的方法:
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
三種方案都無法解決我的問題,這個時候我想到了在URL傳資料
思考四
把許可權資訊拼接在URL上,這個controller去處理這個URL中的資訊把他存放session,頁面再去非同步請求這個session中的資訊。嗯,邏輯完全沒有問題。在這個過程中遇到一個問題,就是URL中不能有一個特殊符號,比如 []
等,解決問題是將這個資訊轉換為URL編碼,然後在controller層將URL解碼即可。
在這個controller獲取資訊存入session,在來一個非同步請求獲取這個session,問題最終搞定了。
由於部分程式碼涉及公司資訊,這裡就不分享,整體思路感覺還是比較清晰。