詳談 springboot整合shiro

来源:https://www.cnblogs.com/beyond-tester/archive/2023/08/16/17636466.html
-Advertisement-
Play Games

背景: 上文學習了shrio 基本概念後,本章將進一步的落地實踐學習,在springboot中如何去整合shrio,整個過程步驟有個清晰的瞭解。 利用Shiro進行登錄認證主要步驟: 1. 添加依賴:首先,在pom.xml文件中添加Spring Boot和Shiro的相關依賴。 <!-- Sprin ...


背景:

上文學習了shrio 基本概念後,本章將進一步的落地實踐學習,在springboot中如何去整合shrio,整個過程步驟有個清晰的瞭解。

 

利用Shiro進行登錄認證主要步驟:

1. 添加依賴:首先,在pom.xml文件中添加Spring Boot和Shiro的相關依賴。

<!-- Spring Boot -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Shiro -->
<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-spring-boot-starter</artifactId>
    <version>1.7.1</version>
</dependency>

2. 創建Shiro配置類:創建一個ShiroConfig類,用於配置Shiro的相關信息和組件。(對於配置的解釋和作用見第三章雜談

@Configuration
public class ShiroConfig {

    // 配置安全管理器
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myRealm());
        return securityManager;
    }

    // 配置自定義Realm
    @Bean
    public MyRealm myRealm() {
        return new MyRealm();
    }

    // 配置Shiro過濾器
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        shiroFilterFactoryBean.setLoginUrl("/login"); // 設置登錄頁面
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized"); // 設置未授權頁面

        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();

        // 允許匿名訪問的路徑
        filterChainDefinitionMap.put("/login", "anon");
        filterChainDefinitionMap.put("/static/**", "anon");

        // 需要認證才能訪問的路徑
        filterChainDefinitionMap.put("/**", "authc");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
}

 3. 創建自定義Realm:創建一個MyRealm類,繼承AuthorizingRealm並實現相關方法,用於處理認證和授權邏輯

public class MyRealm extends AuthorizingRealm {

    // 處理認證邏輯
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        // 從token中獲取用戶名
        String username = (String) authenticationToken.getPrincipal();

        // 模擬從資料庫或其他存儲中獲取用戶信息
        // 例如,從資料庫中查詢用戶信息並返回
        String dbPassword = "123456"; // 假設從資料庫中查詢的密碼是123456

        // 返回認證信息,包括用戶名和密碼
        return new SimpleAuthenticationInfo(username, dbPassword, getName());
    }

    // 處理授權邏輯
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 從PrincipalCollection中獲取用戶名
        String username = (String) principalCollection.getPrimaryPrincipal();

        // 模擬從資料庫或其他存儲中獲取用戶角色和許可權信息
        // 例如,從資料庫中查詢用戶對應的角色和許可權並返回
        Set<String> roles = new HashSet<>();
        roles.add("admin"); // 假設用戶擁有admin角色

        Set<String> permissions = new HashSet<>();
        permissions.add("user:read"); // 假設用戶擁有user:read許可權

        // 創建授權信息
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        authorizationInfo.setRoles(roles);
        authorizationInfo.setStringPermissions(permissions);

        return authorizationInfo;
    }
}

4. 創建登錄介面和登錄頁面:創建一個登錄介面處理用戶的登錄請求

@Controller
public class LoginController {

    @GetMapping("/login")
    public String login() {
        return "login";
    }

    @PostMapping("/login")
    public String doLogin(String username, String password) {
        // 執行登錄邏輯
        Subject currentUser = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);

        try {
            currentUser.login(token); // 執行登錄
            return "redirect:/home"; // 登錄成功後跳轉到首頁
        } catch (AuthenticationException e) {
            return "redirect:/login-error"; // 登錄失敗後跳轉到錯誤頁面
        }
    }
}

整體的執行流程:

  1. 用戶在瀏覽器中訪問登錄頁面,輸入用戶名和密碼,並點擊登錄按鈕。

  2. Controller層的LoginController類中的doLogin方法被調用,該方法接收用戶名和密碼作為參數。

  3. 創建一個Subject對象,該對象代表當前正在與應用程式交互的用戶。

  4. 創建一個UsernamePasswordToken對象,將用戶名和密碼設置為該對象的屬性。

  5. 調用Subject對象的login方法,將UsernamePasswordToken對象作為參數傳遞進去。

  6. Subject對象將UsernamePasswordToken對象傳遞給Shiro進行認證。

  7. Shiro框架會調用MyRealm類中的doGetAuthenticationInfo方法,該方法用於處理認證邏輯。

  8. doGetAuthenticationInfo方法中,從UsernamePasswordToken對象中獲取用戶名。

  9. 可以根據需要,從資料庫或其他存儲中獲取與用戶名對應的用戶信息,例如密碼等。

  10. 將獲取到的用戶信息與UsernamePasswordToken對象中的密碼進行比較,判斷用戶是否通過認證。

  11. 如果認證成功,創建一個SimpleAuthenticationInfo對象,將用戶名、資料庫中的密碼和Realm名稱作為參數傳遞給它。

  12. SimpleAuthenticationInfo對象會被返回給Shiro框架,表示認證成功。

  13. Shiro框架會將認證成功的信息保存在Subject對象中。

  14. 如果認證失敗,將拋出AuthenticationException異常。

  15. doLogin方法中,通過捕獲AuthenticationException異常,可以處理登錄失敗的情況,例如重定向到登錄失敗頁面。

  16. 如果登錄成功,可以根據需要執行一些操作,例如重定向到首頁或其他需要登錄後才能訪問的頁面。

總結起來,整個執行流程如下:

  1. 用戶輸入用戶名和密碼,並提交登錄表單。
  2. Controller層的LoginController類中的doLogin方法接收到登錄請求。
  3. 創建Subject對象,代表當前用戶。
  4. 創建UsernamePasswordToken對象,將用戶名和密碼設置為其屬性。
  5. 調用Subject對象的login方法,將UsernamePasswordToken對象作為參數傳入。
  6. Shiro框架調用MyRealm類中的doGetAuthenticationInfo方法,處理認證邏輯。
  7. doGetAuthenticationInfo方法中,獲取用戶名和密碼,並與資料庫中的信息進行比較。
  8. 如果認證成功,返回一個SimpleAuthenticationInfo對象,表示認證通過。
  9. 如果認證失敗,拋出AuthenticationException異常。
  10. doLogin方法中,根據認證結果執行相應的操作,例如重定向到登錄成功頁面或登錄失敗頁面。

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 垃圾回收(Garbage Collection)是一種記憶體管理機制,用於檢測和清理不再被程式使用的記憶體,這些不再被使用的記憶體就被稱為垃圾。垃圾回收器會在 JS 引擎(瀏覽器或者 nodejs)內部周期性地運行,一般情況下無需開發者手 ...
  • 通常在頁面中嵌套iframe的情況下還需要進行消息傳遞的通信需求。一般分為兩種情況: 1.iframe里的鏈接與父頁面鏈接是非跨域 這種情況處理比較簡單,直接在父級頁面下就可以寫腳本控制iframe里的元素,同時對iframe里的元素進行操作,例如綁定事件,當事件觸發時發送消息給父級頁面。 具體實踐 ...
  • 在 Vue3 中,有許多與響應式相關的函數,例如 toRef、toRefs、isRef、unref 等等。合理地使用這些函數可以在實際開發中大大提高效率。本文將詳細介紹這些函數的用法,讓我們在實際開發中知道應該使用哪些 API 並能夠熟練地回答面試官的相關問題。 ## ref() 大家對於 ref ...
  • 1、安裝tinymce編輯器 npm i tinymcenpm i @tinymce/tinymce-vue 或: yarn add tinymce yarn add @tinymce/tinymce-vue 2、配置中文語言包 地址:中文語言包 註:最好將語言包放在public/langs/或st ...
  • 在本篇技術博文中,我們將深入探討 Uniapp 框架中如何封裝介面,以簡化開發流程並提高效率。介面封裝是一種重要的開發策略,它不僅可以減少代碼量,還能提高代碼的復用性和維護性。 通過閱讀本文,你將深入瞭解 Uniapp 中封裝介面的重要性和優勢,並學會如何實施介面封裝,以提高開發效率和代碼的可維護... ...
  • —————— BEGIN —————— 1、測試對象條件 作為測試對象的醫院信息平臺(或系統)必須具備軟體著作權證書,運行一年以上並通過初驗。 2、標準符合性測試內容包括 3 部分 數據集標準符合性測試 依據標準 WS445-2014、WS 375.9-2012、WS 376.1-2013 的要求, ...
  • 1.3 分層架構演進 1.3.1 傳統四層架構 將領域模型和業務邏輯分離出來,並減少對基礎設施、用戶界面甚至應用層邏輯的依賴,因為它們不屬業務邏輯。將一個夏雜的系統分為不同的層,每層都應該具有良好的內聚性,並且只依賴於比其自身更低的層。 傳統分層架構的基礎設施層位於底層,持久化和消息機制便位於該層。 ...
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 本篇概覽 - 一個應用同時連接多個資料庫進行操作,這是 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...