Apache Shiro 配置参数详解
Apache Shiro 2.2.1 配置参数详解:解析 shiro.ini 三大段(main、users、roles)的写法与生效规则,实测打印 SecurityManager、IniRealm、SessionManager、sessionDAO 的默认组件与超时默认值,逐项给出含义与调整方式,并验证 [main] 段覆盖全局会话超时,附默认值总览与生产配置模板,全程实测。
Apache Shiro 配置参数详解
目标:系统讲解 Apache Shiro 2.2.1 的核心配置项。以 shiro.ini 的 [main]/[users]/[roles] 三段配置为主线,逐项给出默认 SecurityManager、Realm、SessionManager、sessionDAO 的实测默认值、含义与修改方式,并用 [main] 段覆盖全局会话超时验证生效。所有参数均在 Ubuntu 22.04.5 + OpenJDK 17 + Shiro 2.2.1 环境实测。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS
- Java:OpenJDK 17.0.20.1
- 构建工具:Apache Maven 3.6.3
- Shiro 版本:2.2.1(shiro-core 及其传递模块)
- 示例工程目录:
/root/shiro-demo/ - 配置文件:
src/main/resources/shiro.ini(默认)、src/main/resources/shiro-tuned.ini(覆盖验证) - 演示账号:root / admin / alice(密码统一 q1w2e3r4)
二、前置条件
-
已安装 JDK 17 与 Maven,并能编译运行示例工程(见《Apache Shiro 构建并运行示例应用指南》):
cd /root/shiro-demo mvn -q compile -
已了解 IniSecurityManagerFactory 加载
classpath:shiro.ini的基本用法。
三、配置查看与修改方式
Shiro 以 Ini 配置 + 组件装配为核心。Ini 配置文本在 shiro.ini 中维护;组件默认值可通过程序打印核实。两类「查看/修改」入口如下:
| 配置层 | 对象/入口 | 主要参数 | 查看与修改方式 |
|---|---|---|---|
| 配置文件 | shiro.ini 的 [main] 段 | 组件装配与组件属性 | 修改 ini 后重新构建 SecurityManager |
| 账号数据 | shiro.ini 的 [users] 段 | 账号、密码、角色 | 直接增删行 |
| 授权数据 | shiro.ini 的 [roles] 段 | 角色与权限串 | 直接增删行 |
| 安全组件 | SecurityManager / Realm | 实现类、realm 列表 | 程序打印类名核实(ConfigDemo) |
| 会话管理 | SessionManager | globalSessionTimeout、sessionValidationInterval、sessionDAO | 程序打印默认值,[main] 段覆盖 |
💡 说明:shiro.ini 路径以
classpath:前缀表示从类路径加载;src/main/resources/下的文件经mvn compile后会拷贝到target/classes/生效。
四、参数总览(实测默认值)
以下默认值全部由示例工程 ConfigDemo 运行打印(见「六、默认组件实测」),未实测项不列入:
| 参数/组件 | 实测默认值 | 说明 |
|---|---|---|
| SecurityManager 实现 | org.apache.shiro.mgt.DefaultSecurityManager | IniSecurityManagerFactory 构建出的默认实现 |
| Realm | iniRealm(org.apache.shiro.realm.text.IniRealm) | 依据 [users]/[roles] 段隐式构建并自动挂载 |
| SessionManager 实现 | org.apache.shiro.session.mgt.DefaultSessionManager | 会话管理器实现 |
| globalSessionTimeout | 1800000 ms(30 分钟) | 全局会话超时时间 |
| sessionValidationInterval | 3600000 ms(1 小时) | 会话校验调度间隔 |
| sessionDAO | org.apache.shiro.session.mgt.eis.MemorySessionDAO | 会话存储实现(内存) |
五、shiro.ini 三段配置详解
示例工程默认配置文件 /root/shiro-demo/src/main/resources/shiro.ini:
[main]
# IniSecurityManagerFactory 解析本文件时,依据 [users]/[roles] 隐式构建 IniRealm 并挂到 SecurityManager
[users]
root = q1w2e3r4, admin
admin = q1w2e3r4, user, deployer
alice = q1w2e3r4, user
[roles]
admin = *
user = app:read, app:write
deployer = app:deploy
5.1 [main] 段
- 作用:装配组件。每一行「beanName = 全限定类名」定义一个组件实例,随后可用「beanName.属性 = 值」或「securityManager.sessionManager = $sessionManager」这样的写法把组件挂到 SecurityManager。
- 默认行为:[main] 段留空时,IniSecurityManagerFactory 会依据 [users]/[roles] 段隐式构建 IniRealm 并挂到 SecurityManager(示例 shiro.ini 的 [main] 段只有注释,未显式装配任何组件)。
- 段内自定义对象用
$beanName引用(Ini 风格的对象图装配)。
5.2 [users] 段
- 格式:
账号 = 密码, 角色1, 角色2,逗号后第一个字段是密码,其余是角色名。 - 实测数据:root 挂 admin 角色;admin 挂 user 与 deployer 两个角色;alice 仅挂 user。
- 认证行为:IniRealm 依据该段完成 UsernamePasswordToken 的凭据比对;账号不存在抛 UnknownAccountException,密码不匹配抛 IncorrectCredentialsException(实测回显见《Apache Shiro 构建并运行示例应用指南》第七章)。
5.3 [roles] 段
- 格式:
角色 = 权限串1, 权限串2;权限串支持资源:操作分层写法,*表示全部权限。 - 实测数据:admin =
*(全权限);user =app:read, app:write;deployer =app:deploy。 - 判定行为:isPermitted 按权限串匹配(root 因通配符对 app:delete 也为 true,alice 则为 false,实测见《Apache Shiro 构建并运行示例应用指南》第八章)。
六、默认组件实测(SecurityManager、Realm、SessionManager)
6.1 测试程序源码
创建 /root/shiro-demo/src/main/java/demo/ConfigDemo.java,打印默认组件与关键默认值:
package demo;
import org.apache.shiro.ini.IniSecurityManagerFactory;
import org.apache.shiro.lang.util.Factory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.session.mgt.SessionManager;
/**
* 辅助类:打印 IniSecurityManagerFactory 构建出的默认组件与 SessionManager 关键默认值。
*/
public class ConfigDemo {
public static void main(String[] args) {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");
SecurityManager sm = factory.getInstance();
System.out.println("SecurityManager class = " + sm.getClass().getName());
DefaultSecurityManager dsm = (DefaultSecurityManager) sm;
for (Realm realm : dsm.getRealms()) {
System.out.println("realm = " + realm.getName() + " (" + realm.getClass().getName() + ")");
}
SessionManager sessionManager = dsm.getSessionManager();
System.out.println("SessionManager class = " + sessionManager.getClass().getName());
DefaultSessionManager dSessionManager = (DefaultSessionManager) sessionManager;
System.out.println("globalSessionTimeout = " + dSessionManager.getGlobalSessionTimeout() + " ms");
System.out.println("sessionValidationInterval = " + dSessionManager.getSessionValidationInterval() + " ms");
System.out.println("sessionDAO class = " + dSessionManager.getSessionDAO().getClass().getName());
}
}
6.2 运行与回显
cd /root/shiro-demo && mvn exec:java -Dexec.mainClass=demo.ConfigDemo
实测回显(应用段与构建结果):
SecurityManager class = org.apache.shiro.mgt.DefaultSecurityManager
realm = iniRealm (org.apache.shiro.realm.text.IniRealm)
SessionManager class = org.apache.shiro.session.mgt.DefaultSessionManager
globalSessionTimeout = 1800000 ms
sessionValidationInterval = 3600000 ms
sessionDAO class = org.apache.shiro.session.mgt.eis.MemorySessionDAO
[INFO] BUILD SUCCESS
[INFO] Total time: 0.633 s
6.3 逐项解读
- SecurityManager = DefaultSecurityManager:shiro-core 内建的默认安全管理器实现,同时承担认证(Authenticator)、授权(Authorizer)与会话管理(SessionManager)三个职责。
- realm = iniRealm(org.apache.shiro.realm.text.IniRealm):realm 名称固定为
iniRealm,由 [users]/[roles] 段数据驱动;realm.getName() 的返回值即iniRealm。 - SessionManager = DefaultSessionManager:默认会话管理器,内建会话校验调度线程。
- globalSessionTimeout = 1800000 ms:全局会话超时 30 分钟,超时后 会话失效、Subject 需重新认证。
- sessionValidationInterval = 3600000 ms:每 1 小时调度一次会话有效性校验,清理已过期会话。
- sessionDAO = MemorySessionDAO:会话保存在内存;进程重启后会话全部丢失,分布式场景需替换为外部存储实现。
七、SessionManager 参数覆盖验证
7.1 覆盖配置文件
创建 /root/shiro-demo/src/main/resources/shiro-tuned.ini,在 [main] 段显式装配 SessionManager 并把全局超时改为 2 小时:
[main]
# 在 [main] 中显式构建 SessionManager 并挂到 securityManager,覆盖全局会话超时为 2 小时
sessionManager = org.apache.shiro.session.mgt.DefaultSessionManager
securityManager.sessionManager = $sessionManager
sessionManager.globalSessionTimeout = 7200000
[users]
root = q1w2e3r4, admin
admin = q1w2e3r4, user, deployer
[roles]
admin = *
user = app:read, app:write
deployer = app:deploy
三行的含义:
sessionManager = 全限定类名:实例化一个 DefaultSessionManager 组件。securityManager.sessionManager = $sessionManager:把该组件挂到 securityManager 的 sessionManager 属性($引用上文 bean)。sessionManager.globalSessionTimeout = 7200000:设置该组件的 globalSessionTimeout 属性,单位 ms(7200000 ms = 2 小时)。
7.2 验证程序源码
创建 /root/shiro-demo/src/main/java/demo/ConfigDemo2.java:
package demo;
import org.apache.shiro.ini.IniSecurityManagerFactory;
import org.apache.shiro.lang.util.Factory;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.DefaultSessionManager;
import org.apache.shiro.session.mgt.SessionManager;
/**
* 辅助类:验证 shiro-tuned.ini 中 [main] 段的 SessionManager 装配与超时覆盖是否生效。
*/
public class ConfigDemo2 {
public static void main(String[] args) {
Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-tuned.ini");
SecurityManager sm = factory.getInstance();
System.out.println("SecurityManager class = " + sm.getClass().getName());
DefaultSecurityManager dsm = (DefaultSecurityManager) sm;
SessionManager sessionManager = dsm.getSessionManager();
System.out.println("SessionManager class = " + sessionManager.getClass().getName());
DefaultSessionManager dSessionManager = (DefaultSessionManager) sessionManager;
System.out.println("globalSessionTimeout = " + dSessionManager.getGlobalSessionTimeout() + " ms");
}
}
7.3 运行与回显
cd /root/shiro-demo
mvn -q compile
mvn exec:java -Dexec.mainClass=demo.ConfigDemo2
实测回显(应用段):
[demo.ConfigDemo2.main()] INFO org.apache.commons.beanutils.FluentPropertyBeanIntrospector - Error when creating PropertyDescriptor for public void org.apache.shiro.session.mgt.AbstractNativeSessionManager.setAttribute(org.apache.shiro.session.mgt.SessionKey,java.lang.Object,java.lang.Object) throws org.apache.shiro.session.InvalidSessionException! Ignoring this property.
[demo.ConfigDemo2.main()] INFO org.apache.commons.beanutils.FluentPropertyBeanIntrospector - Error when creating PropertyDescriptor for public void org.apache.shiro.session.mgt.AbstractNativeSessionManager.setTimeout(org.apache.shiro.session.mgt.SessionKey,long) throws org.apache.shiro.session.InvalidSessionException! Ignoring this property.
SecurityManager class = org.apache.shiro.mgt.DefaultSecurityManager
SessionManager class = org.apache.shiro.session.mgt.DefaultSessionManager
globalSessionTimeout = 7200000 ms
7.4 结果解读
globalSessionTimeout = 7200000 ms:默认 1800000 ms 被成功覆盖为 7200000 ms,证明 [main] 段的组件装配与属性覆盖语法生效。- 开头两条 FluentPropertyBeanIntrospector INFO:commons-beanutils 1.11.0 反射扫描重载 setter(setAttribute/setTimeout 带 SessionKey 参数)时的已知良性提示,日志明确写了
Ignoring this property,不影响配置生效与运行。 - SecurityManager 与 SessionManager 实现类保持不变,仅属性值变化,符合预期。
八、生产配置模板
💡 适用场景:单体 Java 应用(演示服务、内部管理后台),会话保存在本机内存,JVM 堆限制 256–512MB。以下模板的组件与参数均来自本文实测项。
[main]
# 显式装配会话管理器:全局超时 30 分钟,校验间隔 1 小时(与默认值一致的显式写法,便于按需调整)
sessionManager = org.apache.shiro.session.mgt.DefaultSessionManager
securityManager.sessionManager = $sessionManager
sessionManager.globalSessionTimeout = 1800000
sessionManager.sessionValidationInterval = 3600000
[users]
# 演示账号:生产环境必须更换口令,并改用带散列凭据校验的 Realm 方案
root = q1w2e3r4, admin
admin = q1w2e3r4, user, deployer
[roles]
admin = *
user = app:read, app:write
deployer = app:deploy
| 场景 | 建议配置 |
|---|---|
| 演示/功能验证 | 保持全部默认值(超时 30 分钟,内存会话) |
| 内部应用(登录态偏长) | globalSessionTimeout = 7200000(2 小时,实测验证过的写法) |
| 进程内存紧张 | 缩短 globalSessionTimeout,加快过期会话回收,同时约束 JVM 堆 256–512MB |
| 多实例/重启不丢会话 | MemorySessionDAO 为内存实现,需更换会话存储方案(外部存储)后才能满足 |
⚠️ 注意:[users] 段的密码为明文比对;生产系统应改用支持散列凭据的 Realm 与 CredentialsMatcher 方案,不要沿用明文口令配置。
九、常见问题
Q1:修改 shiro.ini 后不生效?
确认两点:一是文件位于 src/main/resources/ 并重新执行 mvn compile(拷贝到 target/classes);二是程序加载的路径与修改的文件一致(本文验证程序分别加载 classpath:shiro.ini 与 classpath:shiro-tuned.ini)。
Q2:运行时打印 FluentPropertyBeanIntrospector 的两条 INFO 是否为错误?
不是。这是 commons-beanutils 1.11.0 对重载 setter 的反射提示,日志自带 Ignoring this property,配置照常生效(见 7.3 与 7.4)。
Q3:globalSessionTimeout 的单位与默认值?
单位毫秒,实测默认 1800000 ms(30 分钟);示例覆盖为 7200000 ms(2 小时)验证成功。
Q4:[main] 段留空为什么也有 IniRealm?
IniSecurityManagerFactory 解析 shiro.ini 时,若存在 [users]/[roles] 段会隐式构建名为 iniRealm 的 IniRealm 并挂到 SecurityManager(实测 realm 名称与类名见 6.2)。显式装配时才需要在 [main] 段声明组件。
十、参考链接
- Apache Shiro 配置文档:
https://shiro.apache.org/configuration.html - Ini 与 SecurityManager:
https://shiro.apache.org/configuration.html#ini-configuration - Session Management 文档:
https://shiro.apache.org/session-management.html - IniRealm API:
https://shiro.apache.org/static/2.2.1/apidocs/org/apache/shiro/realm/text/IniRealm.html