背景: 上文學習了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"; // 登錄失敗後跳轉到錯誤頁面 } } }
整體的執行流程:
-
用戶在瀏覽器中訪問登錄頁面,輸入用戶名和密碼,並點擊登錄按鈕。
-
Controller層的
LoginController
類中的doLogin
方法被調用,該方法接收用戶名和密碼作為參數。 -
創建一個
Subject
對象,該對象代表當前正在與應用程式交互的用戶。 -
創建一個
UsernamePasswordToken
對象,將用戶名和密碼設置為該對象的屬性。 -
調用
Subject
對象的login
方法,將UsernamePasswordToken
對象作為參數傳遞進去。 -
Subject
對象將UsernamePasswordToken
對象傳遞給Shiro進行認證。 -
Shiro框架會調用
MyRealm
類中的doGetAuthenticationInfo
方法,該方法用於處理認證邏輯。 -
在
doGetAuthenticationInfo
方法中,從UsernamePasswordToken
對象中獲取用戶名。 -
可以根據需要,從資料庫或其他存儲中獲取與用戶名對應的用戶信息,例如密碼等。
-
將獲取到的用戶信息與
UsernamePasswordToken
對象中的密碼進行比較,判斷用戶是否通過認證。 -
如果認證成功,創建一個
SimpleAuthenticationInfo
對象,將用戶名、資料庫中的密碼和Realm名稱作為參數傳遞給它。 -
SimpleAuthenticationInfo
對象會被返回給Shiro框架,表示認證成功。 -
Shiro框架會將認證成功的信息保存在
Subject
對象中。 -
如果認證失敗,將拋出
AuthenticationException
異常。 -
在
doLogin
方法中,通過捕獲AuthenticationException
異常,可以處理登錄失敗的情況,例如重定向到登錄失敗頁面。 -
如果登錄成功,可以根據需要執行一些操作,例如重定向到首頁或其他需要登錄後才能訪問的頁面。
總結起來,整個執行流程如下:
- 用戶輸入用戶名和密碼,並提交登錄表單。
- Controller層的
LoginController
類中的doLogin
方法接收到登錄請求。 - 創建
Subject
對象,代表當前用戶。 - 創建
UsernamePasswordToken
對象,將用戶名和密碼設置為其屬性。 - 調用
Subject
對象的login
方法,將UsernamePasswordToken
對象作為參數傳入。 - Shiro框架調用
MyRealm
類中的doGetAuthenticationInfo
方法,處理認證邏輯。 - 在
doGetAuthenticationInfo
方法中,獲取用戶名和密碼,並與資料庫中的信息進行比較。 - 如果認證成功,返回一個
SimpleAuthenticationInfo
對象,表示認證通過。 - 如果認證失敗,拋出
AuthenticationException
異常。 - 在
doLogin
方法中,根據認證結果執行相應的操作,例如重定向到登錄成功頁面或登錄失敗頁面。