0%

Shiro简介

Shiro 简介:轻量级 Java 安全框架的核心与实现

Apache Shiro 是一款功能强大且易于使用的开源安全框架,专注于解决 Java 应用中的身份认证、授权、会话管理和加密等安全问题。与 Spring Security 相比,Shiro 以其简洁的 API、灵活的配置和较低的学习成本,成为中小型应用和快速开发场景的首选安全框架。

Shiro 的核心功能

Shiro 围绕 “安全” 提供四大核心功能,覆盖了大多数应用的安全需求:

核心功能 说明
Authentication(身份认证) 验证用户身份(“你是谁”),如用户名密码登录、第三方登录(OAuth)等。
Authorization(授权) 控制用户权限(“你能做什么”),如判断用户是否有权限访问某个接口或按钮。
Session Management(会话管理) 管理用户会话(即使在非 Web 环境中),支持会话过期、存储、失效等。
Cryptography(加密) 提供安全的加密算法(如 MD5、SHA),用于密码加密、数据脱敏等。

Shiro 的架构与核心对象

架构

Shiro 的架构设计清晰,通过一系列核心对象协同工作,实现安全功能。其整体架构如图所示,核心对象包括SubjectSecurityManagerRealms等。

1. 核心对象详解

(1)Subject
  • 定义:与应用交互的 “当前操作用户”(可以是人类用户、第三方服务等)。
  • 特点:
    • 所有操作都通过Subject发起(如登录、权限验证);
    • 内部绑定到SecurityManager,实际功能由SecurityManager代理实现;
    • 可通过SecurityUtils.getSubject()获取当前线程的Subject实例。
(2)SecurityManager
  • 定义:Shiro 的 “核心引擎”,协调所有安全组件,管理全局安全逻辑。
  • 功能:
    • 管理所有Subject实例;
    • 委托Authenticator进行身份认证,Authorizer进行授权;
    • 集成SessionManagerCacheManager等组件,提供一站式安全服务。
(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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1. 初始化环境(加载shiro.ini配置)
BasicIniEnvironment environment = new BasicIniEnvironment("classpath:shiro.ini");
// 2. 绑定SecurityManager到全局工具类
SecurityUtils.setSecurityManager(environment.getSecurityManager());
// 3. 获取当前用户(Subject)
Subject subject = SecurityUtils.getSubject();
// 4. 构建认证凭证(用户名+密码)
UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");

try {
// 5. 执行登录(认证)
subject.login(token);
System.out.println("认证成功");
} catch (AuthenticationException e) {
System.out.println("认证失败:" + e.getMessage());
}

认证流程拆解:

  1. 应用层:创建UsernamePasswordToken(或其他凭证),调用subject.login(token)
  2. Subject 层DelegatingSubject(默认实现)将请求委托给SecurityManager
  3. SecurityManager 层:委托Authenticator执行认证;
  4. Authenticator 层:
    • 若配置多个 Realm,通过AuthenticationStrategy判断整体结果;
    • 调用 Realm 的getAuthenticationInfo(token)方法,验证凭证(如比对密码);
  5. Realm 层:从数据源(数据库、ini 文件等)获取用户信息,与 token 比对,返回认证结果。

Shiro 的授权过程

授权是在认证通过后,判断用户是否有权限执行某个操作,流程如下:

1
2
3
4
5
6
7
8
9
10
11
12
// 假设已完成认证
Subject subject = SecurityUtils.getSubject();

// 1. 角色验证
if (subject.hasRole("admin")) {
System.out.println("拥有admin角色");
}

// 2. 权限验证
if (subject.isPermitted("user:delete")) {
System.out.println("拥有删除用户的权限");
}

授权流程拆解:

  1. 应用层:调用subject.hasRole()subject.isPermitted()
  2. Subject 层:委托SecurityManager执行授权;
  3. SecurityManager 层:委托Authorizer处理;
  4. Authorizer 层:
    • 调用 Realm 的getAuthorizationInfo(PrincipalCollection)方法,获取用户的角色和权限;
    • 比对用户拥有的角色 / 权限与目标角色 / 权限,返回验证结果。

Shiro 的优势与适用场景

优势:

  • 轻量级:API 简洁,学习成本低,适合快速集成;
  • 跨环境:支持 Web、桌面、移动端等多种环境,不限于 Spring;
  • 灵活扩展:Realm、SessionDAO 等组件可自定义,适配各种数据源;
  • 功能完整:覆盖认证、授权、会话、加密核心安全需求。

适用场景:

  • 中小型 Java 应用(Web 或非 Web);
  • 快速开发场景,需简化安全配置;
  • 需集成多种数据源(数据库、LDAP、缓存)的安全验证;
  • 非 Spring 生态的应用(如纯 JavaSE 项目)。

总结

Shiro 通过SubjectSecurityManagerRealms等核心对象,构建了一套完整的安全框架,实现了身份认证、授权、会话管理和加密等功能。其简洁的设计和灵活的扩展机制,使其成为 Java 应用中安全解决方案的优选

欢迎关注我的其它发布渠道