Shiro 安全框架:核心组件全解析(2025–2026 实用版)
Apache Shiro 是一个功能强大但相对轻量级的 Java 安全框架,主要解决认证(Authentication)、授权(Authorization)、加密(Cryptography)、会话管理(Session Management) 和 缓存(Caching) 等常见安全需求。
相比 Spring Security,Shiro 的最大优势在于简单、直观、易于理解和快速上手,特别适合中小型项目、中后台系统、传统 Web 项目以及需要快速集成权限管理的场景。
下面按Shiro 最核心的 5 大组件 + 实际工作流程完整拆解(基于 Shiro 2.x 系列,2025–2026 仍在主流使用的版本)。
1. Shiro 核心架构总览(5 大组件)
| 组件名称 | 中文名 | 主要职责 | 是否必须配置 | 常见实现类 / 接口 |
|---|---|---|---|---|
| Subject | 主体 | 当前用户/请求的“身份”代表 | 必须 | DefaultSubject |
| SecurityManager | 安全管理器 | Shiro 的“大脑”,所有组件的协调者 | 必须 | DefaultSecurityManager |
| Authenticator | 认证器 | 负责登录验证(用户名密码、token 等) | 必须 | ModularRealmAuthenticator |
| Authorizer | 授权器 | 负责权限检查(有没有某个角色/权限) | 必须 | ModularRealmAuthorizer |
| Realm | 领域/数据源 | 实际获取用户、角色、权限数据的桥梁 | 必须 | JdbcRealm、IniRealm、自定义 Realm |
一句话记忆口诀:
一个 Subject → 通过一个 SecurityManager → 调用 Authenticator 认证 + Authorizer 授权 → 都从 Realm 取数据
2. 核心组件逐一深度解析
2.1 Subject(主体)——“当前用户”的唯一代表
Subject subject = SecurityUtils.getSubject();
// 最常用三句代码
subject.login(token); // 登录
subject.isAuthenticated(); // 是否已登录
subject.hasRole("admin"); // 是否有某个角色
subject.isPermitted("user:edit:123"); // 是否有某个权限
subject.logout(); // 退出
- Subject 本身不存储任何信息,它只是一个门面(Facade)
- 所有操作最终都会委托给 SecurityManager
2.2 SecurityManager(安全管理器)——Shiro 的心脏
它是 Shiro 所有功能的统一调度中心,包含以下子组件:
- Authenticator(认证器)
- Authorizer(授权器)
- SessionManager(会话管理器)
- CacheManager(缓存管理器)
- EventBus(事件总线,可选)
最常见配置方式(Spring Boot + Shiro)
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(realm);
// 可选:自定义 Session、Cache 等
return securityManager;
}
2.3 Realm(领域)——最重要、最常自定义的部分
Realm 是 Shiro 与实际数据源(数据库、LDAP、配置文件、缓存等)之间的桥梁。
Shiro 内置几种 Realm:
| Realm 类型 | 适用场景 | 数据来源 | 是否常用 |
|---|---|---|---|
| IniRealm | 学习/演示 | .ini 文件 | 很少 |
| PropertiesRealm | 简单配置 | .properties 文件 | 很少 |
| JdbcRealm | 传统 JDBC 项目 | 数据库(JDBC) | 中等 |
| LdapRealm | 企业使用 AD/LDAP | LDAP 目录 | 特定场景 |
| 自定义 Realm | 99% 生产项目 | 任意(MyBatis、JPA、Redis 等) | 最常用 |
自定义 Realm 经典写法(最推荐)
public class ShiroRealm extends AuthorizingRealm {
@Autowired
private UserService userService;
// 认证(登录时调用)
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
throws AuthenticationException {
String username = (String) token.getPrincipal();
User user = userService.findByUsername(username);
if (user == null) {
throw new UnknownAccountException("用户不存在");
}
// 返回 SimpleAuthenticationInfo(用户名, 数据库密码, realmName)
return new SimpleAuthenticationInfo(
username,
user.getPassword(),
getName()
);
}
// 授权(访问受限资源时调用)
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
// 角色
Set<String> roles = userService.findRoles(username);
info.setRoles(roles);
// 权限(字符串形式)
Set<String> permissions = userService.findPermissions(username);
info.setStringPermissions(permissions);
return info;
}
}
2.4 Authenticator(认证器)
默认实现:ModularRealmAuthenticator(支持多 Realm 认证)
- 至少有一个 Realm 成功就算认证通过
- 支持 AtLeastOneSuccessfulStrategy(默认)、AllSuccessfulStrategy 等
2.5 Authorizer(授权器)
默认实现:ModularRealmAuthorizer
- 合并所有 Realm 返回的权限/角色
- 支持 PermissionResolver(将字符串转为 Permission 对象,如 “user:edit:*”)
3. Shiro 完整认证 & 授权流程(面试必考)
浏览器 → 提交用户名/密码 → UsernamePasswordToken
↓
Subject.login(token)
↓
SecurityManager → Authenticator → 遍历所有 Realm
↓
Realm.doGetAuthenticationInfo() → 查库比对密码
↓
密码正确 → 登录成功 → Subject 绑定 Session
↓
访问 /admin → Shiro 拦截器 → Subject.isPermitted("admin:view")
↓
SecurityManager → Authorizer → 遍历 Realm
↓
Realm.doGetAuthorizationInfo() → 返回角色/权限集合
↓
有权限 → 放行 / 无权限 → 抛 AuthorizationException → 跳转 403
4. Shiro 在 Spring Boot 中的典型集成(2025–2026 主流写法)
@Configuration
public class ShiroConfig {
@Bean
public Realm realm() {
return new ShiroRealm();
}
@Bean
public SecurityManager securityManager(Realm realm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
manager.setRealm(realm);
// 可选:禁用 Session(前后端分离)
// manager.setSessionManager(new DefaultSessionManager());
return manager;
}
@Bean
public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) {
ShiroFilterFactoryBean filter = new ShiroFilterFactoryBean();
filter.setSecurityManager(securityManager);
// 常用过滤器链
Map<String, String> filterMap = new LinkedHashMap<>();
filterMap.put("/login", "anon"); // 匿名访问
filterMap.put("/admin/**", "authc, roles[admin]"); // 登录 + admin 角色
filterMap.put("/user/**", "authc, perms[user:view]"); // 登录 + 具体权限
filterMap.put("/**", "authc"); // 其余全部需登录
filter.setFilterChainDefinitionMap(filterMap);
filter.setLoginUrl("/login");
filter.setSuccessUrl("/index");
filter.setUnauthorizedUrl("/403");
return filter;
}
}
5. Shiro vs Spring Security 快速对比(2025–2026 视角)
| 维度 | Shiro | Spring Security | 推荐场景 |
|---|---|---|---|
| 学习曲线 | 低(配置简单) | 中高(概念多、配置复杂) | Shiro 更适合快速上手 |
| 功能完整性 | 足够(认证+授权+会话+缓存) | 更强大(OAuth2、JWT、Method Security 等) | Spring Security 更适合复杂项目 |
| 与 Spring 集成 | 良好 | 原生最佳 | Spring Boot 官方更推 Security |
| 前后端分离友好度 | 非常友好(易做无状态) | 友好(但配置稍繁琐) | Shiro 传统项目更省心 |
| 社区活跃度(2026) | 中等 | 极高 | Security 长期维护更有保障 |
结论:
- 快速开发、中小型项目、传统 Web → 选 Shiro
- 需要 OAuth2、微服务、安全要求极高 → 选 Spring Security
- 两者混合 → 很多项目用 Shiro 做基础认证 + Spring Security 做 OAuth2
你现在最想深入 Shiro 的哪个部分?
A. 自定义 Realm + 数据库完整实现(MyBatis / JPA)
B. 前后端分离下 Shiro + JWT 无状态认证方案
C. Shiro 缓存(Ehcache / Redis)配置与优化
D. Shiro 过滤器链 + 自定义 Filter 实战
E. Shiro 与 Spring Boot 3 + Spring Security 6 共存方案
告诉我字母,我继续带你写代码!