1、實現StatelessAuthcFilter:攔截所有stateless的請求
(1)isAccessAllowed():攔截后先進入該方法。直接返回false,交由onAccessDenied處理鑒權與登錄邏輯。(原因參照說明1)
(2)參照抽象類AccessControlFilter重寫兩個onAccessDenied方法。先獲取mappedValue處理鑒權,鑒權若通過則調用另一onAccessDenied處理登錄邏輯。(此處省略onAccessDenied兩個實現的代碼片段)
(3)處理登錄邏輯的onAccessDenied()中。獲取客戶端傳輸的sequence、token、params以及由以上三者經密鑰生成的digest(摘要)。
(4)生成StatelessToken。StatelessToken繼承自Shiro的AuthenticationToken,擴展了一些屬性如username(token)、sequence(時間戳)、clientDigest(客戶端生成的摘要)、params(除了摘要以外的參數)。
(5)委托給Realm進行登錄驗證。
(6)自定義函數onLoginFail,根據傳入錯誤類型返回相應的json提示用戶登錄失敗。以下情況,調用onLoginFail,並return false。
情況一:sequence、token、digest中有一個為空。(參數不全)
情況二:當前時間戳減去sequence,時間差超過一定時間。(可能為重放攻擊)
情況三:委托為Realm進行登錄,拋出異常。(各種原因的登錄失敗)
2、實現StatelessRealm
(1)重寫doGetAuthenticationInfo方法(校驗身份)。
首先,獲取到StatelessAutncFilter中設置的StatelessToken,其屬性sequence、token、params、clientDigest。
其次,根據token字符串到數據庫中查找Token對象(用戶從移動端用賬號密碼登錄時生成,包含token字符串,唯一密鑰,當前User,有效期相關)。
再次,根據和前端同樣的規則用secret生成密鑰。
然后,在服務器端生成客戶端參數的消息摘要。
最后,進行身份校驗。
(2)重寫doGetAuthorizationInfo方法(鑒權)。
3、配置applicationContext-shiro.xml
(1)配置StatelessRealm,關閉緩存。
(2)配置SecurityManager,在其realms的property中配置StatelessRelam。
(2)配置StatelessAuthcFilter,並在filterChainDefinitions配置stateless過濾器。
說明:
1、StatelessAuthcFitler的每次請求都需要登錄,必須進入onAccessDenied處理登錄邏輯。如果在isAccessAllowed()中處理鑒權,通過則不進入onAccessDenied,不通過則進入onAccessDenied,達不到“stateless[customer]”的角色限制效果。