shiro-core 框架分析
2025-1-2 12:40:16 Author: www.freebuf.com(查看原文) 阅读量:0 收藏

freeBuf

主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

本篇文章只阐述最核心内容,从整体描述shiro-core,目的是能在研究shiro的漏洞时有一个全局观,因此不可能涉及全部细节。

image

图中圆也是接口

  • 整体初始化流程【Abstraction:实现】【Process: 流程】

    ==所有的开始,都是从配置开始==,配置的方式主要有两种:编程式配置,配置文件读取与解析(利用反射机制,调用构造函数,setter,getter),初始化的对象,主要是SecurityManager

    Apache Shiro Configuration | Apache Shiro

SecurtyManager

securityManager只负责调度,它会将大部分功能委托给其他组件完成:

Authenticator负责身份认证,Authorizer负责访问控制,SessionManager负责会话管理

image

image

核心功能:

(1)登入,登出,创建subject

(2) 身份认证

(3)授权

(4)会话管理

类图:数据据结构

image

Subject

代表的是外部实体,一般是一次请求

设计模式

  • builder pattern

  • 工厂模式

实现

  1. 数据结构

​ 内部类:Subject.Builder

image

​ 默认实现:DelegatingSubject:其字段就是其存储的信息

image

  • 创建过程

image

  1. 核心算法

    SecurityManager的默认实现: DefaultSecurityManager:

    初始化SubjectContext,然后调用 doCreateSubject(context)创建subject,(其底层是委托给SubjectFactory)

    image

    当创建subject后,会将当前subject的信息存储到会话中(主要是Principals, isAuthenticated,)

  2. 关于SubjectContext

    图中下面的部分是Map中的key

    image

Authenticator

负责身份认证,也就是检查principal和credentials

1 设计模式

  • AOP(编程思想,而不是模式)&& 策略模式

    Filter、Interceptor、Spring AOP 的对比

    Filter、Interceptor 和 Spring AOP 都体现了面向切面编程(AOP)的思想,本质上是为了解决横切关注点的问题。它们的主要区别在于粒度(切入点的层次不同),但其核心思想一致:将业务逻辑和通用逻辑(如认证、日志、事务)解耦,实现关注点分离。

    AOP来源于 关注点分离原则

    类型切入点
    Filter程序级别:Servlet
    Interceptor类级别 : Controller
    spring AOP方法级别

    所以,我们可以说,Filter、Interceptor 和 AOP 都是面向切面编程的不同层次实现

  • 工厂模式

    RealmFatory

  • 委托:将数据查询委托给Realm

  • 策略

2 实现

  • 数据结构/类图

image

  • 身份验证流程

    整体流程:层层代理

    image

    具体流程:分为single和Multi两个分支,single部分只做最简单的验证,也就是根据Principal和credentials查询相应信息,查得到就是验证成功,查不到或发生任何异常就验证失败,而multi部分只是在single的基础上添加一些aop操作

    image

    部分源码

    ModularRealmAuthenticator::

    image

Authorizer

Apache Shiro Authorization | Apache Shiro

Authorization Elements

  • Permision = Resource + Actions

  • Role 是权限的集合

  • User

实现

1.数据结构/类图

image

可以看出 委托模式和 代理模式(jdk) 在代码形式上是一致的,因为委托模式可以看作“没有任何代理逻辑的代理模式”

授权流程(工作流程)

image

核心算法

只要所拥有的权限集合中任意一个权限**包含(implies)**了所需权限则授权成功

//参数1:当前操作所需的权限
//参数2:当前用户所拥有的授权信息
protected boolean isPermitted(Permission permission, AuthorizationInfo info) {
        Collection<Permission> perms = getPermissions(info);  //所拥有的权限集合
        if (perms != null && !perms.isEmpty()) {
            for (Permission perm : perms) {        
                if (perm.implies(permission)) {//表示perm 包含 permission
                    return true;
                }
            }
        }
        return false;
    }

SessionManager

Session Management | Apache Shiro

Like other core architectural components in Shiro, the SessionManageris a top-level component maintained by the SecurityManager

设计模式

  1. 监听

  2. DAO&委托

    SessionManagerimplementations delegate these Create/Read/Update/Delete (CRUD) operations to an internal component, the SessionDAO, which reflects the Data Access Object (DAO)design pattern.

实现

1.数据结构/类图

image

SessionDAO默认实现是用内存,由shiro实现,其他方式需要由Application自己实现.

shiro-web的WebsessionManager 的两个实现分别对应native(用shiro自己实现的会话管理) 和 serveltcontainer(调用ServletContainer实现的会话管理

源码:ServletContainerSessionManager::

public Session getSession(SessionKey key) throws SessionException {
  if (!WebUtils.isHttp(key)) {
      String msg = "SessionKey must be an HTTP compatible implementation.";
      throw new IllegalArgumentException(msg);
  }

  HttpServletRequest request = WebUtils.getHttpRequest(key);

  Session session = null;

 //调用servlet container实现的接口
  HttpSession httpSession = request.getSession(false);  

  if (httpSession != null) {
      session = createSession(httpSession, request.getRemoteHost());
  }

  return session;
}

Realms

负责获取验证信息,访问控制(权限检查),shiro提供了一些简单实现,但通常由Application根据业务实现

Apache Shiro Realms | Apache Shiro

shiro-web

  • shiro-web是shiro-core的wrapper

    其特征都是 ”实现一方,调用一方“ 注:调用不一定要显式的调用(代码上的),隐式调用也算,比如子类对于没有重写父类的方法,其字节码的函数引用与父类的一致,所以也可算作子类调用了父类的函数

    比如shiro-web实现了Filter接口,从而使得Tomcat可以调用,同时ShiroFilter,又调用了WebSubject,

    从抽象的接口的意义上讲,Shiro***Filter调用WebSubject相关验证和授权接口,但这些接口是继承自Subject的,所以会调用Subject接口,从而调用了shiro-core

    如图:红色代表shiro-core, 蓝色是shiro-web

    image

    从具体实现的意义过程来讲,当然是类调用类,但这是实现,不是"概念",从抽象意义讨论调用过程比较契合概念.

    同时由于其是软件级别的wrapper,shiro-core与其wrapper(shiro-web) 不是完全单向的调用关系,某些情况shiro-core会调用wrapper中的实现,比如SessionManager的两种实现

    同时shiro-web与Servlet容器也不是单向关系

  • session管理冲突:

    Session管理的使用,servlet容器(Tomcat) 已经实现了 的(Tomcat的Session管理(一) - coldridgeValley - 博客园 (cnblogs.com)),所以到底是使用 shrio提供的SessionManager,还是Tomcat已经实现的 是一个需要考虑的选择,shiro当然考虑到了这点

    Apache Shiro Web Support | Apache Shiro| session_management

  • subject 不在是“用户”级别 更确切的讲是“请求”级别,因为Servlet Container是以请求为单位进行处理,所以对它来说“主体” 是 请求

  • 具体适配方式以后展开

Reference


什么是计算机软件设计中的 wrapper 技术 - 知乎 (zhihu.com)

Apache Shiro Reference Documentation | Apache Shiro

Tomcat的Session管理(一) - coldridgeValley - 博客园 (cnblogs.com)

本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022


文章来源: https://www.freebuf.com/articles/web/413356.html
如有侵权请联系:admin#unsafe.sh