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 阅读更多 →
Qwen3.6-27B模型在5060Ti与V100显卡上的推理性能对比

Qwen3.6-27B模型在5060Ti与V100显卡上的推理性能对比

1. 项目背景与测试目标最近在本地大模型推理领域,Qwen3.6-27B这款开源模型因其优秀的性能表现获得了广泛关注。作为一名长期关注AI推理硬件选型的从业者,我决定对两款主流显卡——NVIDIA 5060Ti 16G和V100 32G进行实测对比,看看在Qwen3.6-27B…

2026/7/21 23:38:09 阅读更多 →
在线教育平台的 AI 代码生成实践:课件页面模板化与质量保障体系

在线教育平台的 AI 代码生成实践:课件页面模板化与质量保障体系

在线教育平台的 AI 代码生成实践:课件页面模板化与质量保障体系 在线教育平台的课件页面开发,长期面临两个核心矛盾:一是课件数量大、迭代快,手工编写页面效率不足;二是课件质量参差不齐,缺少统一的代码规范…

2026/7/21 23:38:09 阅读更多 →

最新新闻

2026年嵩县代账公司盘点:团队资质与服务模式全解析

2026年嵩县代账公司盘点:团队资质与服务模式全解析

2026年嵩县代账公司盘点:团队资质与服务模式全解析2026年财税服务现状与创业痛点分析近年来,随着企业注册数量的持续增长,嵩县及周边地区的财税服务需求日益多样化。对于初创企业而言,如何在复杂的税务政策下确保账务合规&#xf…

2026/7/22 1:39:27 阅读更多 →
家庭回忆录AI助手架构复盘:从单文件原型到分层架构的技术选型变更

家庭回忆录AI助手架构复盘:从单文件原型到分层架构的技术选型变更

家庭回忆录AI助手架构复盘:从单文件原型到分层架构的技术选型变更 一、从纸上原型到线上系统:一个家庭场景AI产品的真实演进 家庭回忆录AI助手的出发点是一个朴素的需求:帮助年长家庭成员整理散落在手机相册、微信聊天记录和手写便签中的零散…

2026/7/22 1:39:27 阅读更多 →
Spring AI(2) :AI应用开发技术架构

Spring AI(2) :AI应用开发技术架构

文章目录AI应用开发技术架构Prompt问答Function CallingRAG Embeddings (Retrieval Augumented Generation)Fine-tuning模型微调AI应用开发技术架构 AI应用开发技术架构分为4种 Prompt问答 Function Calling RAG Embeddings (Retrieval Augumented Generation) Fine-tuning模…

2026/7/22 1:39:27 阅读更多 →
3S技术编程应用:遥感、测绘与GIS开发实战

3S技术编程应用:遥感、测绘与GIS开发实战

1. 3S技术领域与编程能力的结合点3S技术作为地理信息科学的核心支柱,由遥感(Remote Sensing)、地理信息系统(GIS)和全球导航卫星系统(GNSS,常与测绘结合)三大技术组成。在这个数字化…

2026/7/22 1:39:27 阅读更多 →
SQL数据库命令详解与优化实践

SQL数据库命令详解与优化实践

1. 数据库命令基础解析数据库命令是与数据库管理系统(DBMS)进行交互的核心工具,它们构成了数据操作的基础语言。无论是简单的查询还是复杂的系统管理,都需要通过特定的命令来完成。这些命令按照功能可以分为数据查询语言(DQL)、数据操作语言(DML)、数据定…

2026/7/22 1:39:27 阅读更多 →
MySQL Binlog膨胀问题解析与优化策略

MySQL Binlog膨胀问题解析与优化策略

1. 当Binlog膨胀到无法解析时:问题本质与典型场景 上周五凌晨2点,我接到运维同事的紧急电话——某核心业务数据库的Binlog突然暴涨到120GB,导致监控系统触发了磁盘空间告警。更棘手的是,DBA团队尝试用常规方法解析这些日志时&…

2026/7/22 1:38:27 阅读更多 →

日新闻

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

TI DSP系统配置模块SYSCFG详解:中断机制与主设备优先级配置实战

1. 项目概述与SYSCFG模块的核心价值在嵌入式系统,尤其是像TI C6000系列这样的高性能DSP开发中,我们常常会与芯片手册里那些密密麻麻的寄存器打交道。很多开发者可能更关注算法实现、内存优化或者外设驱动,但对于一个稳定、高效的系统而言&…

2026/7/22 0:00:26 阅读更多 →
微信Server酱:高到达率的应急通知方案实践

微信Server酱:高到达率的应急通知方案实践

1. 为什么我们需要"最次"的通知方案? 在数字化协作环境中,消息通知系统的重要性不言而喻明。但现实情况是,企业级通知方案往往需要复杂的API对接(如企业微信、钉钉、飞书),个人开发者的小项目又经…

2026/7/22 0:00:26 阅读更多 →
甲方要的“简洁“PPT,到底是简洁还是省事?

甲方要的“简洁“PPT,到底是简洁还是省事?

甲方说"简洁一点",乙方听到的是"少做几页"。甲方说"不要太复杂",乙方理解成"别放图表了"。结果交过去,甲方说"我说的简洁不是这个意思"。"简洁"这个词在PPT语境里,是…

2026/7/22 0:00:26 阅读更多 →

周新闻

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

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

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

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

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

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

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

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

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

2026/7/21 8:25:39 阅读更多 →

月新闻