Shiro安全框架:核心组件全解析

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/LDAPLDAP 目录特定场景
自定义 Realm99% 生产项目任意(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 视角)

维度ShiroSpring 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 共存方案

告诉我字母,我继续带你写代码!

文章已创建 4138

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部