Shiro权限框架整合Spring配置全解析
本文详细解读了如何将Apache Shiro权限框架与Spring框架进行无缝整合,打造安全可靠的应用系统。从添加Maven依赖开始,逐步讲解了自定义Realm的创建,包括身份验证(AuthenticationInfo)和授权(AuthorizationInfo)的实现,以及SecurityManager的配置。重点介绍了ShiroFilterFactoryBean的使用,通过设置URL拦截规则,实现灵活的权限控制。此外,还深入探讨了在Spring Boot中启用Shiro的方法,以及利用`@RequiresRoles`和`@RequiresPermissions`注解进行权限控制。文章还针对分布式环境下的Session共享问题,提供了Shiro自带Session管理、Spring Session以及第三方方案等多种解决方案。最后,还介绍了如何通过集成CAS或自定义OAuth 2.0协议实现单点登录(SSO),以及如何自定义认证流程,例如增加验证码校验等功能,助力开发者构建更安全、更灵活的Spring应用。
Shiro整合Spring的核心在于通过配置将Shiro的安全管理功能嵌入Spring应用上下文中。1. 添加Maven依赖,包括shiro-spring、spring-context、spring-beans、spring-web及日志组件;2. 创建自定义Realm类继承AuthorizingRealm,实现doGetAuthorizationInfo和doGetAuthenticationInfo方法;3. 配置ShiroConfig类,定义MyRealm、SecurityManager、ShiroFilterFactoryBean等Bean,并设置URL拦截规则和权限控制支持;4. 在Spring Boot启动类中启用Shiro;5. 使用@RequiresRoles或@RequiresPermissions注解实现权限控制;6. 分布式环境下处理Session共享可通过Shiro自带Session管理、Spring Session或第三方方案如Redis实现;7. 实现SSO可通过集成CAS或自定义OAuth 2.0协议;8. 自定义认证流程需创建自定义AuthenticationToken和Realm,并在认证方法中添加额外校验逻辑如验证码验证。
Shiro整合Spring,核心在于将Shiro的安全管理功能无缝嵌入到Spring的应用上下文中,实现权限控制、认证和授权等功能。这需要配置Shiro的各种组件,并让Spring管理它们的生命周期。

解决方案
添加Maven依赖: 首先,在你的
pom.xml
文件中添加Shiro和Spring相关的依赖。<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.9.0</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.23</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.3.23</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.3.23</version> </dependency> <!-- 引入slf4j日志 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.36</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency>
版本号根据实际情况调整,Spring Web依赖主要用于Web应用。
配置Shiro的Realm: Realm是Shiro用于获取用户身份验证和授权信息的组件。你需要创建一个Realm实现类,并配置它。
public class MyRealm extends AuthorizingRealm { @Autowired private UserService userService; // 假设你有一个UserService @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { String username = (String) principals.getPrimaryPrincipal(); User user = userService.findByUsername(username); // 从数据库获取用户 if (user == null) { return null; } SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo(); // 添加角色 user.getRoles().forEach(role -> authorizationInfo.addRole(role.getName())); //添加权限 user.getPermissions().forEach(permission -> authorizationInfo.addStringPermission(permission.getName())); return authorizationInfo; } @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { String username = (String) token.getPrincipal(); User user = userService.findByUsername(username); // 从数据库获取用户 if (user == null) { return null; // 用户不存在 } return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName()); } }
这里假设你有一个
UserService
用于从数据库获取用户信息。注意,密码通常需要进行加密存储,并使用Shiro提供的加密工具类进行验证。配置Shiro的SecurityManager:
SecurityManager
是Shiro的核心组件,用于管理所有的Subject,并协调认证和授权。@Configuration public class ShiroConfig { @Bean public MyRealm myRealm() { return new MyRealm(); } @Bean public DefaultWebSecurityManager securityManager() { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(myRealm()); return securityManager; } @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon"); // 允许匿名访问 filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/**", "authc"); // 其他所有请求需要认证 shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.setLoginUrl("/login"); // 未认证跳转URL shiroFilterFactoryBean.setSuccessUrl("/index"); // 认证成功URL shiroFilterFactoryBean.setUnauthorizedUrl("/403"); // 未授权URL return shiroFilterFactoryBean; } @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; } @Bean public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { return new LifecycleBeanPostProcessor(); } @Bean @DependsOn("lifecycleBeanPostProcessor") public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator(); defaultAdvisorAutoProxyCreator.setProxyTargetClass(true); return defaultAdvisorAutoProxyCreator; } }
这个配置类定义了Shiro的Realm、SecurityManager和ShiroFilterFactoryBean。
ShiroFilterFactoryBean
定义了URL的拦截规则。AuthorizationAttributeSourceAdvisor
和DefaultAdvisorAutoProxyCreator
用于支持基于注解的权限控制。LifecycleBeanPostProcessor
用于管理Shiro Bean的生命周期。注意@DependsOn
注解,确保lifecycleBeanPostProcessor
先被创建。在Spring Boot启动类中启用Shiro:
@SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
Spring Boot会自动扫描并加载Shiro的配置。
使用Shiro的注解: 你可以在Controller中使用Shiro的注解来控制权限。
@Controller public class MyController { @RequiresRoles("admin") @RequestMapping("/admin") public String adminPage() { return "admin"; } @RequiresPermissions("user:create") @RequestMapping("/user/create") public String createUser() { return "createUser"; } }
@RequiresRoles
用于限制只有具有特定角色的用户才能访问,@RequiresPermissions
用于限制只有具有特定权限的用户才能访问。
Shiro整合Spring后,如何处理session共享问题?
Shiro默认使用Servlet容器的Session管理,但在分布式环境下,Servlet容器的Session无法共享。解决这个问题有几种方法:
- 使用Shiro自带的Session管理: Shiro可以自己管理Session,你需要配置一个
SessionDAO
用于Session的持久化,例如使用Redis或数据库存储Session。 - 使用Spring Session: Spring Session提供了一种统一的Session管理方案,可以与Shiro集成。你需要引入Spring Session的依赖,并配置Session的存储方式。
- 使用第三方Session共享方案: 例如使用Redis Session共享等。
使用Shiro进行单点登录(SSO)如何配置?
Shiro本身不直接提供SSO功能,但可以与其他SSO方案集成。一种常见的做法是:
- 集成CAS (Central Authentication Service): CAS是一种流行的开源SSO解决方案。你需要配置Shiro使用CAS的客户端,将用户的认证委托给CAS服务器。
- 自定义SSO集成: 你也可以自定义SSO集成,例如通过OAuth 2.0协议与其他认证服务器交互。这需要实现自定义的Realm,用于从认证服务器获取用户信息。
如何自定义Shiro的认证流程,例如增加验证码校验?
自定义Shiro的认证流程通常需要以下步骤:
- 自定义AuthenticationToken: 创建一个自定义的
AuthenticationToken
,用于携带验证码等额外信息。 - 自定义Realm: 在自定义的Realm中,重写
doGetAuthenticationInfo
方法,从AuthenticationToken
中获取验证码,并进行校验。如果验证码校验失败,抛出自定义的异常。 - 配置ShiroFilterFactoryBean: 在
ShiroFilterFactoryBean
中,配置自定义的认证过滤器,用于处理认证流程。
在doGetAuthenticationInfo
中,你需要先验证验证码,如果验证码正确,再进行用户身份验证。示例代码:
@Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { MyAuthenticationToken myToken = (MyAuthenticationToken) token; String username = (String) myToken.getPrincipal(); String captcha = myToken.getCaptcha(); // 验证验证码 if (!validateCaptcha(captcha)) { throw new IncorrectCaptchaException("验证码错误"); } User user = userService.findByUsername(username); if (user == null) { return null; // 用户不存在 } return new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName()); }
注意,IncorrectCaptchaException
需要你自定义。同时,MyAuthenticationToken
也需要你自定义,继承自AuthenticationToken
,并添加captcha
属性。
以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于文章的相关知识,也可关注golang学习网公众号。

- 上一篇
- GuavaCache使用教程:Java缓存实现详解

- 下一篇
- Python操作Neo4j:py2neo图数据库入门指南
-
- 文章 · java教程 | 6分钟前 |
- Java反射高级技巧全解析
- 372浏览 收藏
-
- 文章 · java教程 | 6分钟前 |
- RocketMQ安装配置教程详解
- 430浏览 收藏
-
- 文章 · java教程 | 12分钟前 |
- Java记忆游戏:对象比较与状态控制解析
- 276浏览 收藏
-
- 文章 · java教程 | 24分钟前 |
- 线程安全原子POJO:Java并发实战解析
- 244浏览 收藏
-
- 文章 · java教程 | 30分钟前 |
- Java响应式编程实战教程
- 259浏览 收藏
-
- 文章 · java教程 | 39分钟前 |
- Java类继承怎么学?继承原理与代码详解
- 382浏览 收藏
-
- 文章 · java教程 | 42分钟前 |
- DynamoDBGSI唯一性设计解析
- 209浏览 收藏
-
- 文章 · java教程 | 42分钟前 |
- Java性能调优工具及实战案例详解
- 486浏览 收藏
-
- 文章 · java教程 | 45分钟前 |
- MyBatis三种批量更新方法全解析
- 300浏览 收藏
-
- 文章 · java教程 | 48分钟前 |
- Android音量键计次监听实现方法
- 259浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 511次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 498次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 边界AI平台
- 探索AI边界平台,领先的智能AI对话、写作与画图生成工具。高效便捷,满足多样化需求。立即体验!
- 411次使用
-
- 免费AI认证证书
- 科大讯飞AI大学堂推出免费大模型工程师认证,助力您掌握AI技能,提升职场竞争力。体系化学习,实战项目,权威认证,助您成为企业级大模型应用人才。
- 421次使用
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 559次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 660次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 567次使用
-
- 提升Java功能开发效率的有力工具:微服务架构
- 2023-10-06 501浏览
-
- 掌握Java海康SDK二次开发的必备技巧
- 2023-10-01 501浏览
-
- 如何使用java实现桶排序算法
- 2023-10-03 501浏览
-
- Java开发实战经验:如何优化开发逻辑
- 2023-10-31 501浏览
-
- 如何使用Java中的Math.max()方法比较两个数的大小?
- 2023-11-18 501浏览