1、前言在Web項目中,許可權管理及許可權訪問控制為網站訪問安全提供了保障,並且很多項目使用了Session作為快取,結合AOP技術進行token認證和許可權控制。許可權控制流程大致如
2021-06-29 16:36:27
1、前言
在Web項目中,許可權管理及許可權訪問控制為網站訪問安全提供了保障,並且很多項目使用了Session作為快取,結合AOP技術進行token認證和許可權控制。許可權控制流程大致如下圖所示:
現在,如果管理員修改了使用者的角色,或修改了角色的許可權,都會導致使用者許可權發生變化,此時如何實現動態許可權變更,使得前端能夠更新使用者的許可權樹,後端訪問鑑權AOP模組能夠知悉這種變更呢?
2、問題及解決方案
現在的問題是,管理員沒法訪問使用者Session,因此沒法將變更通知此使用者。而使用者如果已經登入,或直接關閉瀏覽器頁面而不是登出操作,Session沒有過期前,使用者訪問介面時,訪問鑑權AOP模組仍然是根據之前快取的Session資訊進行處理,沒法做到動態許可權變更。
使用Security+WebSocket是一個方案,但沒法處理不線上使用者。
解決方案的核心思想是利用ServletContext物件的共享特性,來實現使用者許可權變更的資訊傳遞。然後在AOP類中查詢使用者是否有變更通知記錄需要處理,如果許可權發生變化,則修改response訊息體,新增附加通知資訊給前端。前端收到附加的通知資訊,可更新功能許可權樹,並進行相關處理。
這樣,利用的變更通知服務,不僅後端的使用者url訪問介面可第一時間獲悉變更,還可以通知到前端,從而實現了動態許可權變更。
3、方案實現
3.1、開發變更通知類
服務介面類ChangeNotifyService,程式碼如下:
服務實現類ChangeNotifyServiceImpl,程式碼如下:
此外,變更通知類型,與使用的demo項目有關,目前定義了4種變更通知類型。實際上,除了許可權相關的變更,還有與Session快取欄位相關的變更,也需要通知,否則使用者還是在使用舊資料。
3.2、將變更通知類物件,納入全局配置服務物件中進行管理
全局配置服務類GlobalConfigService,負責管理全局的配置服務物件,服務介面類程式碼如下:
服務實現類GlobalConfigServiceImpl,程式碼如下:
GlobalConfigServiceImpl類,管理了很多配置服務類,此處主要關注ChangeNotifyService類物件。
3.3、使用ServletContext,管理全局配置服務類物件
全局配置服務類在應用啟動時載入到Spring容器中,這樣可實現共享,減少對資料庫的訪問壓力。
實現一個ApplicationListener類,程式碼如下:
在啟動類中,加入該應用偵聽器ApplicationStartup。
現在,有了一個GlobalConfigService類型的全局變數globalConfigService。
3.4、發出變更通知
此處舉2個例子,說明發出變更通知的例子,這兩個例子,都在使用者管理模組,UserManServiceImpl類中。
1)管理員修改使用者資訊,可能導致許可權相關項發生變動,2)禁用使用者,發出變更過通知。
發出通知的相關程式碼如下:
本demo項目的角色相對較少,沒有使用使用者角色關係表,而是使用了bitmap編碼,角色ID取值為2^n,使用者角色組合roles欄位為一個Integer值。如roles=7,表示角色ID組合=[1,2,4]。
另外,如果修改了角色的功能許可權集合,則需要查詢受影響的使用者ID列表,依次發出通知,可類似處理。
3.5、修改Response響應訊息體
Response響應訊息體,為BaseResponse,程式碼如下:
BaseResponse類增加了Additional類型的additional屬性欄位,用於輸出附加資訊。
Additional類的定義如下:
附加資訊類Additional中,個屬性欄位的說明:
notifycode,為通知碼,即可對應通知訊息的類型,目前只有一種,可擴展。notification,為通知碼對應的訊息。通知碼,在ExceptionCodes列舉檔案中定義:
token,用於要求前端更新token。更新token的目的是確認前端已經收到許可權變更通知。因為下次url請求將使用新的token,如果前端未收到或未處理,仍然用舊的token訪問,就要跳到登入頁了。rights,功能樹的字元串輸出,是樹型結構的JSON字元串。3.6、AOP鑑權處理
AuthorizationAspect為鑑權認證的切面類,程式碼如下:
AuthorizationAspect類定義了切點verify(),@Before增強用於鑑權驗證,增加了對變更通知資訊的處理。並利用Session,用rightsChanged屬性欄位記錄需要通知前端的標誌,在@AfterReturning後置增強中根據該屬性欄位的值,進行一步的處理。
@Before增強的doVerify方法中,如果發現角色組合有改變,但仍有訪問此url許可權時,會繼續後續處理,這樣不會中斷業務;如果沒有訪問此url許可權,則返回訪問受限異常資訊,由前端顯示訪問受限頁碼(類似403 Forbidden 頁碼)。
在後置增強@AfterReturning中,限定了返回值類型,如果該請求響應的類型是BaseResponse類型,則修改reponse訊息體,附加通知資訊;如果不是,則不處理,會等待下一個url請求,直到返回類型是BaseResponse類型。也可以採用自定義response的header的方式,這樣,就無需等待了。
generateToken方法,是LoginService類的靜態方法,用於生成使用者token。
至於Utility的parseRoles方法,是將bitmap編碼的roles解析為角色ID的列表,程式碼如下:
getRoleRights方法,是角色功能許可權服務類RoleFuncRightsService的方法,它提供了根據List類型的角色ID列表,快速獲取許可權許可權樹的功能。
如何獲取?
轉發分享此文,後臺私信小編:「 資料 」即可獲取。(注:轉發分享,感謝大家)
相關文章
1、前言在Web項目中,許可權管理及許可權訪問控制為網站訪問安全提供了保障,並且很多項目使用了Session作為快取,結合AOP技術進行token認證和許可權控制。許可權控制流程大致如
2021-06-29 16:36:27
隨著人工智慧逐漸深入地走進我們的工作、生活,越來越多的智慧硬體開始出現在我們的周圍。不同硬體和系統之間的適配也成為了使用者很關心的問題,適配情況也直接影響了消費者的
2021-06-29 16:36:08
我相信許多使用者已經使用了Win10系統一段時間,但Win10的某些功能不是很瞭解。有時我們可能會遇到有限的Win10無線網路,我相信受限制讓每個人都感到非常不舒服,那麼你如何解決
2021-06-29 16:35:41
5G的到來讓我們有了很多全新的體驗,不過對於大眾使用者來說,5G最能夠吸引我們的元素,必須是超越4G數倍的網路速度了。5G能夠擁有著數倍乃至數十倍4G LTE的網路速度,離不開背後所
2021-06-29 16:35:18
每個人都知道一些使用者為Win10計算機設定了登入密碼,但每次Win10都已開啟。這是非常麻煩的。有沒有辦法刪除Win10登入密碼?該方法當然,但您需要手動手動手動。因此,本文分享Win
2021-06-29 16:35:01
這個問題是我們計算機遇到的問題。最近,有朋友遇到0x0000007b的藍色螢幕程式碼,那麼我們應該在遇到這個藍屏程式碼時怎麼辦?讓我們來看看和小編的0x0000007B藍屏程式碼解決方案
2021-06-29 16:34:52