[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.mzph.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作为一种开源框架…