当前位置: 首页 > news >正文

[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官方文档

希望本教程对您有帮助,请点赞❤️收藏⭐关注支持!欢迎在评论区留言交流技术细节!

相关文章:

  • 多模态融合【十九】——MRFS: Mutually Reinforcing Image Fusion and Segmentation
  • GOOSE 协议中MAC配置
  • CVE-2025-31258 macOS远程视图服务沙箱逃逸漏洞PoC已公开
  • JAVA研发+前后端分离,ZKmall开源商城B2C商城如何保障系统性能?
  • 使用scp命令拷贝hadoop100中文件到其他虚拟机中
  • 深度学习之优化器【从梯度下降到自适应学习率算法】(pytorch版)
  • C语言| extern的用法作用
  • TB67S109AFTG, TB67S109AFNG是一款采用PWM斩波器的两相双极步进电机驱动器内置有时钟输入解码器。采用BiCD工艺制造
  • java刷题基础知识
  • 如何通过 Windows 图形界面找到 WSL 主目录
  • 玩转ChatGPT:DeepSeek实战(统一所在地格式)
  • EMQX v5.0通过连接器和规则同步数据
  • STM32 内存
  • 网页常见水印实现方式
  • 牛客周赛96补题 D F
  • 机器学习第八讲:向量/矩阵 → 数据表格的数学表达,如Excel表格转数字阵列
  • 数据集-目标检测系列- 杨桃 数据集 Starfruit>> DataBall
  • 深入学习Zookeeper的知识体系
  • KV cache 缓存与量化:加速大型语言模型推理的关键技术
  • RobotxR1:通过闭环强化学习在大语言模型上实现具身机器人智能
  • 著名连环画家庞邦本逝世
  • 【社论】个人破产探索,要守住“诚实而不幸”的底线
  • 牧原股份子公司与养殖户种猪买卖纠纷案一审胜诉
  • 总导演揭秘十五运会闭幕式:赴一场星辰大海之约
  • 昆明一学校门外小吃摊占满人行道,城管:会在重点时段加强巡查处置
  • 习近平会见委内瑞拉总统马杜罗