Apache Shiro 配置参数详解

Apache Shiro 2.2.1 配置参数详解:解析 shiro.ini 三大段(main、users、roles)的写法与生效规则,实测打印 SecurityManager、IniRealm、SessionManager、sessionDAO 的默认组件与超时默认值,逐项给出含义与调整方式,并验证 [main] 段覆盖全局会话超时,附默认值总览与生产配置模板,全程实测。

Apache ShiroApache Shiro2026/10/12

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)
会话管理SessionManagerglobalSessionTimeout、sessionValidationInterval、sessionDAO程序打印默认值,[main] 段覆盖

💡 说明:shiro.ini 路径以 classpath: 前缀表示从类路径加载;src/main/resources/ 下的文件经 mvn compile 后会拷贝到 target/classes/ 生效。

四、参数总览(实测默认值)

以下默认值全部由示例工程 ConfigDemo 运行打印(见「六、默认组件实测」),未实测项不列入:

参数/组件实测默认值说明
SecurityManager 实现org.apache.shiro.mgt.DefaultSecurityManagerIniSecurityManagerFactory 构建出的默认实现
RealminiRealm(org.apache.shiro.realm.text.IniRealm)依据 [users]/[roles] 段隐式构建并自动挂载
SessionManager 实现org.apache.shiro.session.mgt.DefaultSessionManager会话管理器实现
globalSessionTimeout1800000 ms(30 分钟)全局会话超时时间
sessionValidationInterval3600000 ms(1 小时)会话校验调度间隔
sessionDAOorg.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

三行的含义:

  1. sessionManager = 全限定类名:实例化一个 DefaultSessionManager 组件。
  2. securityManager.sessionManager = $sessionManager:把该组件挂到 securityManager 的 sessionManager 属性($ 引用上文 bean)。
  3. 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