SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權


通過前一篇文章,我們已經實現了前後端分離模式下,使用JSON數據進行前後端交互

主要涉及到

  • 實現 AbstractAuthenticationProcessingFilter 接口,接收JSON格式登錄表單數據,執行登錄校驗
  • 實現 AuthenticationSuccessHandler 接口,登錄成功,返回JSON格式信息
  • 實現 AuthenticationFailureHandler 接口,登錄失敗,返回JSON格式錯誤信息
  • 實現 AccessDeniedHandler 接口,登錄成功,但無資源訪問權限時,返回JSON格式錯誤信息
  • 實現 AuthenticationEntryPoint 接口,未登錄訪問資源時,返回JSON格式錯誤信息

要實現前後端分離,還有一個重要的環節就是存儲用戶登錄狀態,在前一篇文章中,雖然我們實現的JSON格式交互,但是依然使用 session 存儲用戶登錄狀態,但是在實際項目中,客戶端不再是單純的網頁,還可以是手機,平板,公眾號,小程序等,不是每一個客戶端都能夠支持 session+cookie 的模式,怎麼樣可以使用一套代碼,實現多個客戶端登錄、鑑權。

使用 token 代替 session 的流程:

用戶登錄成功,服務端向客戶端分發一個 token,客戶端根據自已的情況自行存儲,並且在每一次請求中附帶上該 token,服務端接收到請求,對該 token 進行校驗,判斷請求用戶登錄狀態,獲取權限信息,實現權限校驗。

目標

整合 SpringSecurity 實現使用 token 進行鑑權。

思路

分成兩個部分,第一部分是登錄,客戶端向服務端發起登錄請求時,

服務端需要生成token並存儲起來,然後將token分發給客戶端,客戶端需要自行存儲該token。

流程圖:

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

在第二部分是登錄成功後,訪問資源時,客戶端需要將登錄時收到的token,附加在請求中,發送給服務端,服務端需要判斷該token的有效性,並通過該token,可以獲取到當前用戶信息。

流程圖:

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

本文使用數據庫存儲token,實際項目中會使用 redis 之類的更高效的存儲

準備工作

創建用戶表 user、角色表 role、用戶角色關係表 user_role 及 token 表

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

操作步驟

添加依賴

引入 Spring Boot Starter 父工程

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

添加 springSecurity 及 mybatisPlus 的依賴,添加後的整體依賴如下

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

配置

配置一下數據源

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

編碼

實體類

角色實體類 Role,實現權限接口 GrantedAuthority

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

用戶實體類 user,實現權限接口 UserDetails,主要方法是 getAuthorities,用於獲取用戶的角色列表

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

用戶角色關係實體

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

Token實體

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

Repository 層

分別為四個實體類添加 Mapper

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

實現 UserDetailsService 接口

UserDetailsService 是 SpringSecurity 提供的登陸時用於根據用戶名獲取用戶信息的接口

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義登錄參數格式

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義登錄過濾器

繼承 SpringSecurity 提供的 AbstractAuthenticationProcessingFilter 類,實現 attemptAuthentication 方法,用於登錄校驗。

本例中,模擬前端使用 json 格式傳遞參數,所以通過 objectMapper.readValue 的方式從流中獲取入參,之後借用了用戶名密碼登錄的校驗,並返回權限對象

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義登陸成功後處理

實現 SpringSecurity 提供的 AuthenticationSuccessHandler 接口,使用 JSON 格式返回

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義登陸失敗後處理

實現 SpringSecurity 提供的 AuthenticationFailureHandler 接口,使用 JSON 格式返回

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義權限校驗失敗後處理

登陸成功之後,訪問接口之前 SpringSecurity 會進行鑑權,如果沒有訪問權限,需要對返回進行處理。實現 SpringSecurity 提供的 AccessDeniedHandler

接口,使用 JSON 格式返回

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義未登錄後處理

實現 SpringSecurity 提供的 AuthenticationEntryPoint 接口,使用 JSON 格式返回

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

自定義 Token 驗證過濾器

客戶端登錄成功時,後臺會把生成的 token 返回給前端,之後客戶端每次請求後臺接口將會把這個 token 附在 header 頭中傳遞給後臺,

後臺會驗證這個 token 是否有效,如果有效就把用戶信息加載至 SpringSecurity 中,如果無效則會跳轉至上一步提供 AuthenticationEntryPoint 進行處理。

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權


註冊

在 configure 方法中將自定義的 jsonAuthenticationFilter 及 tokenAuthenticationFilter 註冊進 SpringSecurity 的過濾器鏈中,並禁用 session。

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

啟動類

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

驗證結果

初始化數據

SpringBoot2.0實戰(27)整合SpringSecurity之使用Token登錄鑑權

源碼地址

本章源碼 : https://gitee.com/gongm_24/spring-boot-tutorial.git


分享到:


相關文章: