[Java實戰]Spring Boot 3 整合 Apache Shiro(二十一)

[Java實戰]Spring Boot 3 整合 Apache Shiro(二十一)

引言

在復雜的業務系統中,安全控制(認證、授權、加密)是核心需求。相比于 Spring Security 的重量級設計,Apache Shiro 憑借其簡潔的 API 和靈活的擴展性,成為許多開發者的優選方案。本文將手把手演示如何在 Spring Boot 3 中整合 Shiro 1.12.0+,實現完整的權限管理功能。

一、環境準備

  • openJDK 17+(Spring Boot 3 強制要求)
  • Spring Boot 3.4.5
  • Apache Shiro 1.12.0(支持 Jakarta EE 9+)
  • Maven/Gradle(本文使用 Maven)
  • Redis(可選,用于會話管理)

二、項目依賴配置

pom.xml 中添加關鍵依賴:

<dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Shiro Core --><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring-boot-starter</artifactId><version>1.12.0</version><classifier>jakarta</classifier></dependency><!-- Servlet API (兼容性) --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency>
</dependencies>

三、核心組件配置

1. Shiro 配置類

創建 ShiroConfig.java 定義安全規則:

@Configuration
public class ShiroConfig {// 注入自定義 Realm@Beanpublic UserRealm userRealm() {return new UserRealm();}// 配置 SecurityManager@Beanpublic SecurityManager securityManager(UserRealm userRealm) {DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();securityManager.setRealm(userRealm);securityManager.setRememberMeManager(rememberMeManager());return securityManager;}// 配置 Shiro 過濾器@Beanpublic ShiroFilterChainDefinition shiroFilterChainDefinition() {DefaultShiroFilterChainDefinition chain = new DefaultShiroFilterChainDefinition();chain.addPathDefinition("/login", "anon");  // 匿名訪問chain.addPathDefinition("/logout", "logout"); // 退出登錄chain.addPathDefinition("/**", "authc"); // 需要認證return chain;}// 記住我功能@Beanpublic RememberMeManager rememberMeManager() {CookieRememberMeManager rememberMeManager = new CookieRememberMeManager();rememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));return rememberMeManager;}
}

2. 自定義 Realm 實現

創建 UserRealm.java 實現認證與授權邏輯:

public class UserRealm extends AuthorizingRealm {@Autowiredprivate UserService userService;// 授權邏輯@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();String username = (String) principals.getPrimaryPrincipal();// 查詢用戶角色和權限User user = userService.findByUsername(username);info.setRoles(user.getRoles());info.setStringPermissions(user.getPermissions());return info;}// 認證邏輯@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {UsernamePasswordToken upToken = (UsernamePasswordToken) token;String username = upToken.getUsername();User user = userService.findByUsername(username);if (user == null) {throw new UnknownAccountException("用戶不存在");}return new SimpleAuthenticationInfo(username, user.getPassword(), ByteSource.Util.bytes(user.getSalt()),getName());}
}

四、權限控制實戰

1. 控制器層注解控制

在 Controller 方法上使用 Shiro 注解:

@RestController
@RequestMapping("/user")
public class UserController {@RequiresRoles("admin")  // 需要admin角色@GetMapping("/list")public ResponseEntity<List<User>> listUsers() {// 業務邏輯}@RequiresPermissions("user:delete") // 需要刪除權限@DeleteMapping("/{id}")public ResponseEntity<Void> deleteUser(@PathVariable Long id) {// 業務邏輯}
}

2. 統一異常處理

通過 @ControllerAdvice 捕獲 Shiro 異常:

@Slf4j
@ControllerAdvice
public class ShiroExceptionHandler {@ExceptionHandler(AuthorizationException.class)public ResponseEntity<ApiResponse<?>> handleAuthError(AuthorizationException e) {return ResponseEntity.status(HttpStatus.FORBIDDEN).body(new ApiResponse<>(403, "權限不足"));}@ExceptionHandler(AuthenticationException.class)public ResponseEntity<ApiResponse<?>> handleLoginError(AuthenticationException e) {return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new ApiResponse<>(401, "認證失敗"));}
}

五、高級功能擴展

1. 集成 Redis 會話管理

@Bean
public SessionDAO sessionDAO() {RedisSessionDAO sessionDAO = new RedisSessionDAO();sessionDAO.setRedisManager(redisManager());return sessionDAO;
}@Bean
public RedisManager redisManager() {RedisManager manager = new RedisManager();manager.setHost("localhost:6379");manager.setDatabase(0);return manager;
}

2. 密碼加密配置

@Bean
public HashedCredentialsMatcher hashedCredentialsMatcher() {HashedCredentialsMatcher matcher = new HashedCredentialsMatcher();matcher.setHashAlgorithmName("SHA-256");matcher.setHashIterations(1024);matcher.setStoredCredentialsHexEncoded(false);return matcher;
}// 在 Realm 中設置
userRealm.setCredentialsMatcher(hashedCredentialsMatcher());

六、常見問題排查

1. 權限注解不生效

  • 檢查是否開啟 AOP 支持:在配置類添加 @EnableAspectJAutoProxy
  • 確認方法為 public 且通過代理對象調用

2. 會話失效異常

  • 檢查 Redis 連接配置
  • 確保 SessionDAO 實現已正確注入

七、性能優化建議

  1. 緩存授權信息:使用 CachingRealm 減少數據庫查詢
  2. 限制會話數量:配置 sessionManager 的全局會話上限
  3. 啟用集群模式:通過 Redis 實現分布式會話

結語

通過本文,您已完成 Spring Boot 3 與 Apache Shiro 的深度整合。相比 Spring Security,Shiro 的配置更簡潔,適合中小型項目快速實現安全控制。建議根據實際業務需求調整認證策略和緩存機制。

擴展閱讀:Shiro官方文檔

希望本教程對您有幫助,請點贊??收藏?關注支持!歡迎在評論區留言交流技術細節!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/905400.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/905400.shtml
英文地址,請注明出處:http://en.pswp.cn/news/905400.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

PyTorch API 6 - 編譯、fft、fx、函數轉換、調試、符號追蹤

文章目錄 torch.compiler延伸閱讀 torch.fft快速傅里葉變換輔助函數 torch.func什么是可組合的函數變換&#xff1f;為什么需要可組合的函數變換&#xff1f;延伸閱讀 torch.futurestorch.fx概述編寫轉換函數圖結構快速入門圖操作直接操作計算圖使用 replace_pattern() 進行子圖…

可觀測性方案怎么選?SelectDB vs Elasticsearch vs ClickHouse

可觀測性&#xff08;Observability&#xff09;是指通過系統的外部輸出數據&#xff0c;推斷其內部狀態的能力。可觀測性平臺通過采集、存儲、可視化分析三大可觀測性數據&#xff1a;日志&#xff08;Logging&#xff09;、鏈路追蹤&#xff08;Tracing&#xff09;和指標&am…

機器人廚師上崗!AI在餐飲界掀起新風潮!

想要了解人工智能在其他各個領域的應用&#xff0c;可以查看下面一篇文章 《AI在各領域的應用》 餐飲業是與我們日常生活息息相關的行業&#xff0c;而人工智能&#xff08;AI&#xff09;正在迅速改變這個傳統行業的面貌。從智能點餐到食材管理&#xff0c;再到個性化推薦&a…

Linux動態庫靜態庫總結

靜態庫生成 g -c mylib.cpp -o mylib.o ar rcs libmylib.a mylib.o 動態庫生成 g -fPIC -shared mylib.cpp -o libmylib.so -fPIC&#xff1a;生成位置無關代碼&#xff08;Position-Independent Code&#xff09;&#xff0c;對動態庫必需。 庫文件使用&#xff1a; 靜態庫&…

通過user-agent來源判斷阻止爬蟲訪問網站,并防止生成[ error ] NULL日志

一、TP5.0通過行為&#xff08;Behavior&#xff09;攔截爬蟲并避免生成 [ error ] NULL 錯誤日志 1. 創建行為類&#xff08;攔截爬蟲&#xff09; 在 application/common/behavior 目錄下新建BlockBot.php &#xff0c;用于識別并攔截爬蟲請求&#xff1a; <?php name…

OpenHarmony平臺驅動開發(十五),SDIO

OpenHarmony平臺驅動開發&#xff08;十五&#xff09; SDIO 概述 功能簡介 SDIO&#xff08;Secure Digital Input and Output&#xff09;由SD卡發展而來&#xff0c;與SD卡統稱為MMC&#xff08;MultiMediaCard&#xff09;&#xff0c;二者使用相同的通信協議。SDIO接口…

使用FastAPI和React以及MongoDB構建全棧Web應用03 全棧開發快速入門

一、什么是全棧開發 A full-stack web application is a complete software application that encompasses both the frontend and backend components. It’s designed to interact with users through a web browser and perform actions that involve data processing and …

Coco AI 開源應用程序 - 搜索、連接、協作、您的個人 AI 搜索和助手,都在一個空間中。

一、軟件介紹 文末提供程序和源碼下載 Coco AI 是一個統一的搜索平臺&#xff0c;可將您的所有企業應用程序和數據&#xff08;Google Workspace、Dropbox、Confluent Wiki、GitHub 等&#xff09;連接到一個功能強大的搜索界面中。此存儲庫包含為桌面和移動設備構建的 Coco 應…

CSS經典布局之圣杯布局和雙飛翼布局

目標&#xff1a; 中間自適應&#xff0c;兩邊定寬&#xff0c;并且三欄布局在一行展示。 圣杯布局 實現方法&#xff1a; 通過float搭建布局margin使三列布局到一行上relative相對定位調整位置&#xff1b; 給外部容器添加padding&#xff0c;通過相對定位調整左右兩列的…

# 實時英文 OCR 文字識別:從攝像頭到 PyQt5 界面的實現

實時英文 OCR 文字識別&#xff1a;從攝像頭到 PyQt5 界面的實現 引言 在數字化時代&#xff0c;文字識別技術&#xff08;OCR&#xff09;在眾多領域中發揮著重要作用。無論是文檔掃描、車牌識別還是實時視頻流中的文字提取&#xff0c;OCR 技術都能提供高效且準確的解決方案…

<C#>log4net 的配置文件配置項詳細介紹

log4net 是一個功能強大的日志記錄工具&#xff0c;通過配置文件可以靈活地控制日志的輸出方式、格式、級別等。以下是對 log4net 配置文件常見配置項的詳細介紹&#xff1a; 根元素 <log4net> 這是 log4net 配置文件的根元素&#xff0c;所有配置項都要包含在該元素內…

編譯docker版openresty

使用alpine為基礎鏡像 # 使用Alpine作為基礎鏡像 FROM alpine:3.18# 替換為阿里云鏡像源&#xff0c;并安裝必要的依賴 RUN sed -i s|https://dl-cdn.alpinelinux.org/alpine|https://mirrors.aliyun.com/alpine|g /etc/apk/repositories && \apk add --no-cache \bui…

conda 輸出指定python環境的庫 輸出為 yaml文件

conda 輸出指定python環境的庫 輸出為 yaml文件。 有時為了項目部署&#xff0c;需要匹配之前的python環境&#xff0c;需要輸出對應的python依賴庫。 假設你的目標環境名為 myenv&#xff0c;運行以下命令&#xff1a; conda env export -n myenv > myenv_environment.ym…

[Java][Leetcode middle] 121. 買賣股票的最佳時機

暴力循環 總是以最低的價格買入&#xff0c;以最高的價格賣出: 例如第一天買入&#xff0c;去找剩下n-1天的最高價格&#xff0c;計算利潤 依次計算到n-1天買入&#xff1b; 比較上述利潤 // 運行時間超時。 o(n^2)public int maxProfit1(int[] prices) {int profit 0;for (i…

克隆虛擬機組成集群

一、克隆虛擬機 1. 準備基礎虛擬機 確保基礎虛擬機已安裝好操作系統&#xff08;如 Ubuntu&#xff09;、Java 和 Hadoop。關閉防火墻并禁用 SELinux&#xff08;如適用&#xff09;&#xff1a; bash sudo ufw disable # Ubuntu sudo systemctl disable firewalld # CentO…

記錄一次使用thinkphp使用PhpSpreadsheet擴展導出數據,解決身份證號碼等信息科學計數法問題處理

PhpSpreadsheet官網 PhpSpreadsheet安裝 composer require phpoffice/phpspreadsheet使用composer安裝時一定要下載php對應的版本&#xff0c;下載之前使用php -v檢查當前php版本 簡單使用 <?php require vendor/autoload.php;use PhpOffice\PhpSpreadsheet\Spreadshee…

前端工程化:從 Webpack 到 Vite

引言 前端工程化是現代Web開發不可或缺的一部分&#xff0c;它通過自動化流程和標準化實踐&#xff0c;提高了開發效率和代碼質量。在這個領域中&#xff0c;構建工具扮演著核心角色&#xff0c;而Webpack和Vite則是其中的兩位重要角色。本文將探討前端工程化的演進歷程&#…

Leetcode 3543. Maximum Weighted K-Edge Path

Leetcode 3543. Maximum Weighted K-Edge Path 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3543. Maximum Weighted K-Edge Path 1. 解題思路 這一題思路上就是一個遍歷的思路&#xff0c;我們只需要考察每一個節點作為起點時&#xff0c;所有長為 k k k的線段的長度&…

香橙派zero3 安卓TV12,更換桌面launcher,開機自啟動kodi

打開開發者模式&#xff0c;連擊版本號&#xff0c;基本上都是這樣。 adb連接 查找桌面包名 adb shell dumpsys activity activities | findstr mResumedActivity 禁用原桌面com.android.tv.launcher&#xff0c;已經安裝了projectivylauncher434.apk桌面。 adb shell pm …

半小時快速入門Spring AI:使用騰訊云編程助手CodeBuddy 開發簡易聊天程序

引言 隨著人工智能&#xff08;AI&#xff09;技術的飛速發展&#xff0c;越來越多的開發者開始探索如何將AI集成到自己的應用中。人工智能正在迅速改變各行各業的工作方式&#xff0c;從自動化客服到智能推薦系統&#xff0c;AI的應用幾乎無處不在。Spring AI作為一種開源框架…