Shiro 简介:轻量级 Java 安全框架的核心与实现
Apache Shiro 是一款功能强大且易于使用的开源安全框架,专注于解决 Java 应用中的身份认证、授权、会话管理和加密等安全问题。与 Spring Security 相比,Shiro 以其简洁的 API、灵活的配置和较低的学习成本,成为中小型应用和快速开发场景的首选安全框架。
Shiro 的核心功能
Shiro 围绕 “安全” 提供四大核心功能,覆盖了大多数应用的安全需求:
| 核心功能 | 说明 |
|---|---|
| Authentication(身份认证) | 验证用户身份(“你是谁”),如用户名密码登录、第三方登录(OAuth)等。 |
| Authorization(授权) | 控制用户权限(“你能做什么”),如判断用户是否有权限访问某个接口或按钮。 |
| Session Management(会话管理) | 管理用户会话(即使在非 Web 环境中),支持会话过期、存储、失效等。 |
| Cryptography(加密) | 提供安全的加密算法(如 MD5、SHA),用于密码加密、数据脱敏等。 |
Shiro 的架构与核心对象

Shiro 的架构设计清晰,通过一系列核心对象协同工作,实现安全功能。其整体架构如图所示,核心对象包括Subject、SecurityManager、Realms等。
1. 核心对象详解
(1)Subject
- 定义:与应用交互的 “当前操作用户”(可以是人类用户、第三方服务等)。
- 特点:
- 所有操作都通过
Subject发起(如登录、权限验证); - 内部绑定到
SecurityManager,实际功能由SecurityManager代理实现; - 可通过
SecurityUtils.getSubject()获取当前线程的Subject实例。
- 所有操作都通过
(2)SecurityManager
- 定义:Shiro 的 “核心引擎”,协调所有安全组件,管理全局安全逻辑。
- 功能:
- 管理所有
Subject实例; - 委托
Authenticator进行身份认证,Authorizer进行授权; - 集成
SessionManager、CacheManager等组件,提供一站式安全服务。
- 管理所有
(3)Realms
定义:Shiro 与应用 “安全数据” 的桥梁(如用户信息、权限数据),可视为 “安全数据源”。
作用:
- 提供身份认证所需的用户信息(如用户名密码);
- 提供授权所需的角色和权限信息;
- 是 Shiro 与数据库、缓存、LDAP 等数据源的对接点。
常用实现类:
IniRealm:从ini配置文件读取用户、角色和权限(适合快速测试)。
- 配置格式:
[users]段定义用户名、密码和角色;[roles]段定义角色和权限。
- 配置格式:
PropertiesRealm:从properties文件读取数据,格式为:
- 用户:
user.username=password,role1,role2 - 角色权限:
role.role1=permission1,permission2
- 用户:
JdbcRealm:通过 JDBC 从数据库读取数据,默认依赖以下 SQL 查询(可自定义):
1
2
3
4
5
6-- 查询用户密码
SELECT password FROM users WHERE username = ?;
-- 查询用户角色
SELECT role_name FROM user_roles WHERE username = ?;
-- 查询角色权限
SELECT permission FROM roles_permissions WHERE role_name = ?;
(4)Authenticator(认证器)
定义:负责执行身份认证逻辑,验证用户提供的凭证(如密码)是否有效。
多 Realm 认证策略:当配置多个 Realm 时,通过AuthenticationStrategy判断认证结果:
| 策略名称 | 说明 |
| ——————————————— | ——————————————————————————— |
|AllSuccessfulStrategy| 所有 Realm 都认证成功,才算整体认证成功(严格模式)。 |
|AtLeastOneSuccessfulStrategy| 至少一个 Realm 认证成功,即算成功(默认策略)。 |
|FirstSuccessfulStrategy| 第一个 Realm 认证成功即算成功,忽略后续 Realm 的结果。 |
(5)Authorizer(授权器)
- 定义:负责权限验证,判断已认证用户是否拥有某个角色或权限。
- 核心方法:
hasRole(String role):判断用户是否拥有指定角色;isPermitted(String permission):判断用户是否拥有指定权限。
(6)SessionManager(会话管理器)
- 定义:管理用户会话,支持 Web 和非 Web 环境(如桌面应用)。
- 功能:会话创建、过期控制、会话存储(内存、数据库等)。
(7)SessionDAO
- 定义:会话数据访问对象,负责会话的 CRUD 操作。
- 应用:如需持久化会话(如存入数据库),可自定义
SessionDAO实现,通过 JDBC 或 Redis 存储会话数据。
(8)CacheManager(缓存管理器)
- 定义:管理安全相关数据(用户、角色、权限)的缓存,提升授权效率。
- 常用实现:与 EhCache、Redis 等缓存框架集成,减少重复查询数据源。
(9)Cryptography(加密模块)
- 定义:提供加密 / 解密工具,支持 MD5、SHA、AES 等算法。
- 应用:密码加密存储(如
new SimpleHash("MD5", password, salt, 1024))。
Shiro 的认证过程
身份认证是 Shiro 最基础的功能,流程如下(基于ini配置示例):
1 | // 1. 初始化环境(加载shiro.ini配置) |
认证流程拆解:
- 应用层:创建
UsernamePasswordToken(或其他凭证),调用subject.login(token); - Subject 层:
DelegatingSubject(默认实现)将请求委托给SecurityManager; - SecurityManager 层:委托
Authenticator执行认证; - Authenticator 层:
- 若配置多个 Realm,通过
AuthenticationStrategy判断整体结果; - 调用 Realm 的
getAuthenticationInfo(token)方法,验证凭证(如比对密码);
- 若配置多个 Realm,通过
- Realm 层:从数据源(数据库、ini 文件等)获取用户信息,与 token 比对,返回认证结果。
Shiro 的授权过程
授权是在认证通过后,判断用户是否有权限执行某个操作,流程如下:
1 | // 假设已完成认证 |
授权流程拆解:
- 应用层:调用
subject.hasRole()或subject.isPermitted(); - Subject 层:委托
SecurityManager执行授权; - SecurityManager 层:委托
Authorizer处理; - Authorizer 层:
- 调用 Realm 的
getAuthorizationInfo(PrincipalCollection)方法,获取用户的角色和权限; - 比对用户拥有的角色 / 权限与目标角色 / 权限,返回验证结果。
- 调用 Realm 的
Shiro 的优势与适用场景
优势:
- 轻量级:API 简洁,学习成本低,适合快速集成;
- 跨环境:支持 Web、桌面、移动端等多种环境,不限于 Spring;
- 灵活扩展:Realm、SessionDAO 等组件可自定义,适配各种数据源;
- 功能完整:覆盖认证、授权、会话、加密核心安全需求。
适用场景:
- 中小型 Java 应用(Web 或非 Web);
- 快速开发场景,需简化安全配置;
- 需集成多种数据源(数据库、LDAP、缓存)的安全验证;
- 非 Spring 生态的应用(如纯 JavaSE 项目)。
总结
Shiro 通过Subject、SecurityManager、Realms等核心对象,构建了一套完整的安全框架,实现了身份认证、授权、会话管理和加密等功能。其简洁的设计和灵活的扩展机制,使其成为 Java 应用中安全解决方案的优选