Apache Shiro框架:Java安全认证与授权实践指南
1. Shiro框架概述Apache Shiro是一个强大且易用的Java安全框架它为应用程序提供了认证、授权、加密和会话管理等功能。作为一个轻量级的安全框架Shiro的设计理念是简化应用程序安全性的实现同时保持足够的灵活性和扩展性。Shiro的核心功能可以概括为以下四个方面认证(Authentication)验证用户身份通常就是我们常说的登录过程授权(Authorization)访问控制决定用户能做什么会话管理(Session Management)用户特定的时间敏感状态管理密码加密(Cryptography)保护数据安全防止敏感信息泄露与其他安全框架相比Shiro的主要优势在于其简单性和易用性。它不需要依赖任何容器或框架可以轻松集成到任何Java应用程序中无论是简单的命令行程序还是复杂的企业级Web应用。2. Shiro核心组件解析2.1 Subject安全操作的主体Subject是Shiro的核心概念代表当前与应用程序交互的用户。这个用户可以是人也可以是第三方服务、后台进程等。Subject封装了当前用户的所有安全操作包括// 获取当前Subject Subject currentUser SecurityUtils.getSubject(); // 登录 currentUser.login(token); // 检查角色 currentUser.hasRole(admin); // 检查权限 currentUser.isPermitted(user:delete);Subject实际上是一个门面(Facade)模式它将大部分安全操作委托给SecurityManager处理。2.2 SecurityManager安全管理的核心SecurityManager是Shiro架构的心脏负责协调所有安全组件的工作。它管理着所有Subject的安全操作并提供以下服务认证管理授权管理会话管理缓存管理在应用程序中通常只需要配置一个SecurityManager实例。配置示例如下[main] # 配置Realm myRealm com.example.MyRealm securityManager.realms $myRealm # 配置缓存管理器 cacheManager org.apache.shiro.cache.ehcache.EhCacheManager securityManager.cacheManager $cacheManager2.3 Realm安全数据桥梁Realm充当Shiro与应用程序安全数据源之间的桥梁。当需要认证用户或检查权限时Shiro会从配置的Realm中查询相关数据。Shiro支持多种Realm实现IniRealm从INI配置文件中读取用户和角色信息JdbcRealm通过JDBC从数据库中获取安全数据LdapRealm连接LDAP目录服务ActiveDirectoryRealm集成Active Directory开发者也可以自定义Realm实现public class MyCustomRealm extends AuthorizingRealm { // 认证逻辑 Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) { // 实现认证逻辑 } // 授权逻辑 Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { // 实现授权逻辑 } }3. 认证流程深度解析3.1 认证基本流程Shiro的认证流程可以概括为以下步骤用户提交身份凭证通常是用户名/密码创建AuthenticationToken对象封装凭证调用Subject.login()方法SecurityManager处理认证请求Realm验证凭证并返回认证信息认证成功或失败处理代码示例// 1. 获取当前用户 Subject currentUser SecurityUtils.getSubject(); // 2. 创建认证令牌 UsernamePasswordToken token new UsernamePasswordToken(username, password); try { // 3. 登录认证 currentUser.login(token); // 认证成功处理 } catch (AuthenticationException ae) { // 认证失败处理 }3.2 认证流程源码分析让我们深入Shiro源码看看认证过程是如何实现的Subject.login()调用// DelegatingSubject.java public void login(AuthenticationToken token) throws AuthenticationException { clearRunAsIdentitiesInternal(); Subject subject securityManager.login(this, token); // 处理认证结果... }SecurityManager处理// DefaultSecurityManager.java public Subject login(Subject subject, AuthenticationToken token) throws AuthenticationException { AuthenticationInfo info authenticate(token); Subject loggedIn createSubject(token, info, subject); onSuccessfulLogin(token, info, loggedIn); return loggedIn; }Authenticator认证// ModularRealmAuthenticator.java protected AuthenticationInfo doAuthenticate(AuthenticationToken token) { CollectionRealm realms getRealms(); if (realms.size() 1) { return doSingleRealmAuthentication(realms.iterator().next(), token); } else { return doMultiRealmAuthentication(realms, token); } }Realm验证// AuthenticatingRealm.java public final AuthenticationInfo getAuthenticationInfo(AuthenticationToken token) { // 1. 尝试从缓存获取 AuthenticationInfo info getCachedAuthenticationInfo(token); if (info null) { // 2. 缓存中没有则调用doGetAuthenticationInfo info doGetAuthenticationInfo(token); // 3. 缓存认证信息 cacheAuthenticationInfoIfPossible(token, info); } // 4. 验证凭证 if (info ! null) { assertCredentialsMatch(token, info); } return info; }3.3 密码匹配与加密Shiro提供了强大的密码匹配和加密功能密码匹配器// 配置密码匹配器 HashedCredentialsMatcher matcher new HashedCredentialsMatcher(); matcher.setHashAlgorithmName(SHA-256); matcher.setHashIterations(1024); myRealm.setCredentialsMatcher(matcher);密码加密// 生成加密密码 String hashedPassword new Sha256Hash(password, salt, 1024).toBase64();盐值使用// 在Realm中设置盐值 info.setCredentialsSalt(ByteSource.Util.bytes(salt));4. 授权机制详解4.1 授权基本概念Shiro的授权模型基于三个核心概念权限(Permission)定义具体的操作权限如user:create角色(Role)权限的集合如admin角色可能包含所有用户管理权限访问控制检查用户是否具有执行某个操作的权限Shiro支持多种授权方式编程式授权if (subject.hasRole(admin)) { // 执行管理操作 } if (subject.isPermitted(user:delete)) { // 删除用户 }注解式授权RequiresRoles(admin) public void deleteUser(User user) { // 只有admin角色可以调用此方法 }标签式授权JSP/GSPshiro:hasRole nameadmin a href/adminAdmin Panel/a /shiro:hasRole4.2 授权流程源码分析Shiro的授权流程同样经过多个组件授权检查入口// AuthorizingSecurityManager.java public void checkPermission(PrincipalCollection principals, String permission) { this.authorizer.checkPermission(principals, permission); }ModularRealmAuthorizer处理// ModularRealmAuthorizer.java public void checkPermission(PrincipalCollection principals, String permission) { assertRealmsConfigured(); for (Realm realm : getRealms()) { if (realm instanceof Authorizer) { ((Authorizer) realm).checkPermission(principals, permission); } } }Realm授权实现// AuthorizingRealm.java public void checkPermission(PrincipalCollection principals, String permission) { AuthorizationInfo info getAuthorizationInfo(principals); checkPermission(permission, info); }4.3 权限字符串设计Shiro的权限字符串通常采用资源:操作:实例的格式基本权限user:create - 创建用户的权限user:delete - 删除用户的权限实例级权限user:edit:123 - 编辑ID为123的用户的权限通配符权限user:* - 所有用户操作权限*:view - 查看所有资源的权限自定义权限解析public class MyPermissionResolver implements PermissionResolver { Override public Permission resolvePermission(String permissionString) { return new MyWildcardPermission(permissionString); } } // 配置权限解析器 securityManager.setPermissionResolver(new MyPermissionResolver());5. 实际应用与最佳实践5.1 集成Spring Boot在Spring Boot中集成Shiro的步骤添加依赖dependency groupIdorg.apache.shiro/groupId artifactIdshiro-spring-boot-starter/artifactId version1.8.0/version /dependency配置ShiroConfiguration public class ShiroConfig { Bean public Realm realm() { MyRealm realm new MyRealm(); realm.setCredentialsMatcher(hashedCredentialsMatcher()); return realm; } Bean public HashedCredentialsMatcher hashedCredentialsMatcher() { HashedCredentialsMatcher matcher new HashedCredentialsMatcher(); matcher.setHashAlgorithmName(SHA-256); matcher.setHashIterations(1024); return matcher; } Bean public SecurityManager securityManager(Realm realm) { DefaultWebSecurityManager securityManager new DefaultWebSecurityManager(); securityManager.setRealm(realm); return securityManager; } }5.2 缓存策略优化Shiro的缓存机制可以显著提高性能启用缓存// 配置缓存管理器 CacheManager cacheManager new EhCacheManager(); securityManager.setCacheManager(cacheManager); // 在Realm中启用缓存 realm.setAuthenticationCachingEnabled(true); realm.setAuthorizationCachingEnabled(true);缓存策略认证缓存缓存用户凭证信息授权缓存缓存用户权限信息缓存失效// 当用户权限变更时清除缓存 public void clearAuthorizationCache(String username) { SimplePrincipalCollection principals new SimplePrincipalCollection(username, realm.getName()); realm.clearCachedAuthorizationInfo(principals); }5.3 常见问题与解决方案认证失败但无异常信息检查Realm的doGetAuthenticationInfo方法是否返回了正确的AuthenticationInfo确保CredentialsMatcher配置正确授权缓存不更新调用realm.clearCachedAuthorizationInfo()清除缓存设置合理的缓存过期时间RememberMe功能失效检查Cookie配置是否正确确保RememberMe管理器已正确配置Session管理问题// 配置Session管理器 DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); sessionManager.setGlobalSessionTimeout(1800000); // 30分钟 securityManager.setSessionManager(sessionManager);性能优化建议使用缓存减少数据库查询合理设计权限字符串避免过于复杂的权限检查对于频繁的权限检查考虑使用RequiresPermissions注解而非编程式检查6. 安全增强与扩展6.1 防止会话固定攻击Shiro提供了会话固定攻击防护Bean public DefaultWebSessionManager sessionManager() { DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); sessionManager.setSessionIdUrlRewritingEnabled(false); // 禁用URL重写 sessionManager.setSessionIdCookieEnabled(true); sessionManager.setDeleteInvalidSessions(true); sessionManager.setSessionValidationSchedulerEnabled(true); sessionManager.setSessionIdCookie(new SimpleCookie(SHRIOSESSIONID)); return sessionManager; }6.2 多Realm策略Shiro支持配置多个Realm并指定认证策略Bean public ModularRealmAuthenticator authenticator() { ModularRealmAuthenticator authenticator new ModularRealmAuthenticator(); authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy()); return authenticator; } Bean public SecurityManager securityManager(Realm realm1, Realm realm2) { DefaultWebSecurityManager securityManager new DefaultWebSecurityManager(); securityManager.setAuthenticator(authenticator()); securityManager.setRealms(Arrays.asList(realm1, realm2)); return securityManager; }6.3 自定义Filter扩展Shiro的Filter机制允许自定义安全控制public class MyCustomFilter extends AccessControlFilter { Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { // 自定义访问控制逻辑 return true; } Override protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { // 访问被拒绝时的处理 return false; } } // 配置Filter MapString, Filter filters new HashMap(); filters.put(custom, new MyCustomFilter()); shiroFilterFactoryBean.setFilters(filters);6.4 分布式会话支持在分布式环境中使用ShiroBean public SessionDAO sessionDAO() { RedisSessionDAO sessionDAO new RedisSessionDAO(); sessionDAO.setRedisManager(redisManager()); return sessionDAO; } Bean public SessionManager sessionManager(SessionDAO sessionDAO) { DefaultWebSessionManager sessionManager new DefaultWebSessionManager(); sessionManager.setSessionDAO(sessionDAO); return sessionManager; }

相关新闻

信号与槽的介绍

信号与槽的介绍

1.信号和槽概述qt中谈到信号,涉及到三个要素:1.信号源:由哪个控件发出信号。2.信号的类型:用户进行不同的操作就可能触发不同的信号(点击按钮触发点击信号、在输入框中移到光标触发移到光标的信号等)。3.信号的处理方式&#xff1…

2026/7/21 23:39:10阅读更多 →
settings.local.json,Claude Code 里最适合个人差异化配置的一层

settings.local.json,Claude Code 里最适合个人差异化配置的一层

最近在梳理 Claude Code 的配置体系时,最容易被低估的文件之一就是 .claude/settings.local.json。它不像 CLAUDE.md 那样负责给模型提供项目背景,也不像 .claude/settings.json 那样适合提交到仓库、统一团队行为。它更像一个贴在本机开发环境旁边的小控制台,专门处理个人偏…

2026/7/21 23:37:10阅读更多 →
海洋观测技术:从传统探测到空天地海一体化

海洋观测技术:从传统探测到空天地海一体化

1. 海洋观测技术发展现状与突破我国海洋观测技术近年来取得了一系列重大突破,从传统的水下探测发展到空天地海一体化观测体系。这种技术飞跃主要体现在三个方面:首先是观测范围的扩展。传统海洋观测主要依靠船舶和浮标等水面设备,观测深度和范…

2026/7/21 23:37:10阅读更多 →
M芯片Mac可靠性解析:架构优势与工程实践

M芯片Mac可靠性解析:架构优势与工程实践

1. M芯片Mac可靠性表现解读:首年故障率仅0.9%的深层分析当看到搭载M系列芯片的Mac首年故障率低至0.9%这个数据时,我的第一反应是翻出过去五年经手的维修记录做交叉验证。作为从PowerPC时代就开始接触苹果设备的从业者,这个数字确实符合实际观…

2026/7/22 1:58:07阅读更多 →
Obsidian-skills终极指南:让AI助手掌握Obsidian的完整教程

Obsidian-skills终极指南:让AI助手掌握Obsidian的完整教程

Obsidian-skills终极指南:让AI助手掌握Obsidian的完整教程 【免费下载链接】obsidian-skills Agent skills for Obsidian. Teach your agent to use Obsidian CLI and open formats including Markdown, Bases, JSON Canvas. 项目地址: https://gitcode.com/GitHu…

2026/7/22 1:58:07阅读更多 →
论文投期刊被要求降AI生成疑似度?一步步降到合格

论文投期刊被要求降AI生成疑似度?一步步降到合格

论文投期刊被要求降AI生成疑似度?一步步降到合格 你是不是刚收到编辑或外审的意见,白纸黑字写着"AI生成疑似度偏高,请修改后再提交",看得心里一沉。你回头翻自己的稿子,明明是一句句琢磨着写出来的&#xf…

2026/7/22 1:58:07阅读更多 →
高精度授时卡在Windows与Linux下的部署与使用指南

高精度授时卡在Windows与Linux下的部署与使用指南

本文面向系统集成人员与运维工程师,介绍基于PCI接口的高精度授时板卡在Windows和Linux操作系统下的设备识别、驱动安装、功能配置全流程,涵盖常见异常的处理方法。 一、设备识别:确认板卡已被操作系统正确枚举 硬件安装完毕后,首先…

2026/7/22 1:58:07阅读更多 →
影刀小技巧:使用 RPA+AI 人脸识别裁切主图

影刀小技巧:使用 RPA+AI 人脸识别裁切主图

作为一个电商从业者,免不了跟各种图片打交道,什么详情图、轮播图、主图等等,很多时候需要我们从各种横的竖的产品图中,去裁切出一张正方形的 1:1 的主图来,让美工手工去切图,当然没问题,可咱是影…

2026/7/22 1:58:07阅读更多 →
Selenium WebDriver 无执行上下文错误:诊断与解决 iframe 加载问题

Selenium WebDriver 无执行上下文错误:诊断与解决 iframe 加载问题

1. 问题定位:当自动化脚本遭遇“无执行上下文”的报错最近在调试一个复杂的Web自动化脚本时,我又一次遇到了那个熟悉又恼人的老朋友:WebDriverException: Message: no such execution context: frame does not have execution context。这个错…

2026/7/22 1:56:07阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →