Shiro源码分析-初始化-SecurityManager

2023-11-18

源码分析的第一篇以SecurityManager的初始化为题。 
根据ini配置文件初始化shiro的代码主要为两段: 
//解析ini文件为Ini对象
Factory<SecurityManager> factory = new IniSecurityManagerFactory(
        "classpath:shiro-config.ini");
//根据Ini对象初始化SecurityManager对象
SecurityManager securityManager = factory.getInstance();

ini文件格式说明请参考: 

http://zh.wikipedia.org/wiki/INI%E6%AA%94%E6%A1%88  
java解析ini的方式也比较多,有兴趣可以参考: 
http://my.oschina.net/tinyframework/blog/214309  
一、Shiro解析ini的步骤如下: 
1、org.apache.shiro.config.IniSecurityManagerFactory类构造方法:  
public IniSecurityManagerFactory(String iniResourcePath) {
        this(Ini.fromResourcePath(iniResourcePath));
    }
将ini文件解析交给Ini的静态方法fromResourcePath完成。并把解析后的Ini对象设置由自身持有 
public IniSecurityManagerFactory(Ini config) {
        setIni(config);
    }
2、org.apache.shiro.config.Ini类解析逻辑:  
public static Ini fromResourcePath(String resourcePath) throws ConfigurationException {
    if (!StringUtils.hasLength(resourcePath)) {
      throw new IllegalArgumentException("Resource Path argument cannot be null or empty.");
    }
    //此处新建Ini对象
    Ini ini = new Ini();
    ini.loadFromPath(resourcePath);
    return ini;
  }

  //根据资源路径获取输入流,交给load方法进行处理
  public void loadFromPath(String resourcePath) throws ConfigurationException {
    InputStream is;
    try {
      is = ResourceUtils.getInputStreamForPath(resourcePath);
    } catch (IOException e) {
      throw new ConfigurationException(e);
    }
    load(is);
  }
ResourceUtils.getInputStreamForPath(resourcePath);这里支持三种获取资源的方式:
classpath shiro-config.ini 从类路径中查找ini配置
url http://....../shiro-config.ini 从指定的url获取ini配置
file D:\shiro-config.ini 从指定的文件路径获取ini配置
3、对获取的资源输入流最终交给文本扫描器Scaner,执行过程代码片段:  
public void load(Scanner scanner) {

    String sectionName = DEFAULT_SECTION_NAME;
    StringBuilder sectionContent = new StringBuilder();

    while (scanner.hasNextLine()) {

      String rawLine = scanner.nextLine();
      String line = StringUtils.clean(rawLine);
      //此处跳过ini文件格式的注释及空值
      if (line == null || line.startsWith(COMMENT_POUND) || line.startsWith(COMMENT_SEMICOLON)) {
        //skip empty lines and comments:
        continue;
      }
      //此处主要获取section部分,根据[]规则
      String newSectionName = getSectionName(line);
      if (newSectionName != null) {
        //此处代码主要用于构造Section对象,并放进sections集合中
        addSection(sectionName, sectionContent);

        //reset the buffer for the new section:
        sectionContent = new StringBuilder();

        sectionName = newSectionName;

        if (log.isDebugEnabled()) {
          log.debug("Parsing " + SECTION_PREFIX + sectionName + SECTION_SUFFIX);
        }
      } else {
        //normal line - add it to the existing content buffer:
        sectionContent.append(rawLine).append("\n");
      }
    }

    //finish any remaining buffered content:
    addSection(sectionName, sectionContent);
  }
上段代码主要是组装ini文件中的section。细心的同学会发现Section、Ini都是实现了Map接口。Section持有的LinkedHashMap容器实际上是当前section中的所有键值对,而Ini持有的LinkedHashMap容器实际上是所有section名称与section对象的键值对。 
至此,ini文件的解析已经完成,其ini中的内容已全部以map的形式存放在Ini实例中。 
至于保存的结果是什么样的呢?以下面的一段配置为例: 
[main]
#authenticator
authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator
authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy
authenticator.authenticationStrategy=$authenticationStrategy
securityManager.authenticator=$authenticator
Ini的sections属性[key=main,value=Section对象],此Section对象内部的props保存了所有main部分key-value映射。目前都是String类型,实例化在下一步完成的。 
二、由Ini实例构造SecurityManager对象 
SecurityManager securityManager = factory.getInstance();
IniSecurityManagerFactory的继承关系为: 
IniSecurityManagerFactory->IniFactorySupport->AbstractFactory->Factory 
这里的getInstance方法由最上级的抽象类:org.apache.shiro.util.AbstractFactory提供,源码如下: 
//该方法只是用于判断是否单例(默认为单例)
  public T getInstance() {
    T instance;
    if (isSingleton()) {
      if (this.singletonInstance == null) {
        this.singletonInstance = createInstance();
      }
      instance = this.singletonInstance;
    } else {
      instance = createInstance();
    }
    if (instance == null) {
      String msg = "Factory 'createInstance' implementation returned a null object.";
      throw new IllegalStateException(msg);
    }
    return instance;
  }
  //由子类IniFactorySupport创建实例
  protected abstract T createInstance();
IniFactorySupport的createInstance实现如下(省略了无关紧要的日志、判断代码): 
public T createInstance() {
    //此处获取解析ini文件产生的Ini对象
    Ini ini = resolveIni();
    T instance;
    if (CollectionUtils.isEmpty(ini)) {
      //如果ini为空,则创建默认实例
      instance = createDefaultInstance();
    } else {
      //根据ini对象创建实例
      instance = createInstance(ini);
    }
    return instance;
  }
  protected abstract T createInstance(Ini ini);

  protected abstract T createDefaultInstance();
上面两个抽象方法,则交给实现类IniSecurityManagerFactory完成了。 
先阅读createDefaultInstance方法源码 
protected SecurityManager createDefaultInstance() {
        return new DefaultSecurityManager();
    }

终于在这个不起眼的地方,看到了初始化最核心的接口SecurityManager了。稍微暂停一下,发个SecurityManager的类图: 


由此图可以看出来,SecurityManager继承了三个接口(认证、授权、session管理),认证授权是安全框架最核心的功能,而shiro提供了自身的session管理机制(这也是shiro的一大亮点)。图中除了DefaultSecurityManager,其它所有类都是抽象类,由此可看出,DefaultSecurityManager是作为默认的安全管理器。 
再来看new DefaultSecurityManager();做的事情 

public DefaultSecurityManager() {
        super();
        this.subjectFactory = new DefaultSubjectFactory();
        this.subjectDAO = new DefaultSubjectDAO();
    }
这里暂时不深究每个构造器所做的具体事情。有兴趣的同学,可一直观察DefaultSecurityManager的所有父类构造器的处理逻辑。 
类名称 构造方法创建的默认对象
DefaultSecurityManager DefaultSubjectFactory,DefaultSubjectDAO
SessionsSecurityManager DefaultSessionManager
AuthorizingSecurityManager ModularRealmAuthorizer
AuthenticatingSecurityManager ModularRealmAuthenticator
RealmSecurityManager
CachingSecurityManager
在上面的表格中已经清晰的描述了各个类所设置的默认对象,至于用途后面再讲解。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Shiro源码分析-初始化-SecurityManager 的相关文章

  • 兼容ios不支持的日期格式

    前段时间开发了一个关于订单展示的页面 要求根据时间筛选出离当前时间最近的订单信息进行展示 因为服务器返回的时间格式都是 YYYY MM DD 也没想那么多 直接拿过来就用了 在安卓上排序都很正常 在测试的时候发现苹果手机展示的订单根本就没有
  • MySQL 查询数据库中所有表的表名、备注

    目录 前言 一 SQL语句 二 SQL实现 前言 查询数据库所有表的表名 备注 其实也是比较常见的操作 比如数据库管理人员可能会经常使用 像我们后端开发人员来说的一个应用场景就是基础代码生成器了 需要获取指定数据库中所有表名及备注进行展示
  • 微信小程序---目录结构

    一 总体目录 大体介绍 1 在utils中定义方法 工具等 主要使用common js暴露接口 2 pages中放我们的页面 3 eslintrc js文件在代码质量审查的时候的代码依赖 4 app js app json app wxss
  • 锚点定位的三种解决方法

    一 学习锚点定位之前的知识储备 1 1 号的作用 代表网页中的一个位置 其右面的字符 就是该位置的标识符 比如 http www example com index html print 就代表网页index html的print位置 浏览
  • Mac 扬声器热插拔

    与windows的IMM接口类似 Mac也采用注册 监听回调的方式来拿到各种设备的插入 拔出 设备采样率 声道的变化等事件 以下以Mac扬声器插拔为例 include
  • Android Studio下修改Module名称

    最近才开始使用Android Studio 相比Eclipse AS有它的亮点和特色 也有它的不足 AS对项目目录的管理说实话我是真的不太喜欢 也可能是才开始用不太习惯吧 好了 废话不多说 闲话少续 下面开始正文 相信大家在使用AS创建Pr
  • tiled卷积神经网络(tiled CNN)

    这个结构是10年Quoc V Le等人提出的 这里的tiled 按照 Lecun的解释是Locally connect non shared 即是局部连接 而且不是共享的 这是针对于权重来说的 本文翻译如有错误 还望指正 谢谢 这篇论文是1
  • 【Vue】前端状态管理之Vuex全解析

    Vuex状态管理全解析 一 状态管理 1 1 状态管理是什么 1 2 为什么要用状态管理 1 2 1 生活中的例子 1 2 2 代码中的例子 1 3 三大框架的状态管理 二 Vuex 2 1 Vuex是什么 2 2 使用Vuex的好处 三
  • struct和typedef struct彻底明白了

    struct和typedef struct 分三块来讲述 1 首先 注意在C和C 里不同 在C中定义一个结构体类型要用typedef typedef struct Student int a Stu 于是在声明变量的时候就可 Stu stu
  • leetcode分类刷题:哈希表(Hash Table)(一、简单的两数之和)

    1 当需要快速判断某元素是否出现在序列中时 就要用到哈希表了 2 本文针对的总结题型为简单的两数之和问题 这种题目的难易程度取决于求解的目标 如果需要返回的是答案的索引 个数 那么就相对简单一些 如果需要返回答案的值构成的二元组 三元组之类
  • 通过网页版堡垒机访问服务器失败,堡垒机远程连接服务器被拒绝

    堡垒机远程连接服务器被拒绝 内容精选 换一换 云堡垒机配置了FTP SFTP远程备份 报请检查服务器密码或网络连接情况错误 不能启动远程备份 选择备份具体某一天日志 提示备份正在执行 但远程服务器未接收到该备份文件 原因一 云堡垒机配置的F
  • Ajax中的XMLHttpRequest对象详解

    原文地址 http www cnblogs com shunyao8210 archive 2008 11 24 1339718 html XMLHttpRequest对象是Ajax技术的核心 在Internet Explorer 5中 X
  • vlfeat 特征检测

    https blog csdn net wangxinsheng0901 article details 79676081 https github com dougalsutherland vlfeat ctypes
  • 【电脑配置】1、Chrome 设置深色模式

    1 在 Chrome 页面地址输入 chrome flags enable force dark 2 将 Dark Mode 设置为 Enabled 3 点击 Relaunch
  • Copy 数据到ppt 中保持对齐

    Copy 一组数据到PPT里 但是有可能在PPT里无法对齐 可以先拷贝到xls里 各个数据项会对齐到单元格 再拷贝到PPT后 这里即可对齐
  • Apifox生成接口文档

    一 http接口 点击添加接口 编辑接口相关信息 点击保存 点击修改文档 点击智能识别 请求示例智能识别 编辑请求参数信息 返回响应智能识别 可添加多个 成功 异常A 异常B等 编辑响应参数信息 添加响应示例 参照返回响应添加 点击保存 接

随机推荐

  • python书写格式_python并的写法

    广告关闭 腾讯云11 11云上盛惠 精选热门产品助力上云 云服务器首年88元起 买的越多返的越多 最高返5000元 最近倒腾python 希望能坚持下去吧发现了个叫codecademy的网站 还不错http www codecademy c
  • 服务器内部操作系统,服务器内部操作系统

    服务器内部操作系统 内容精选 换一换 Atlas 800 训练服务器 型号 9000 安装上架 服务器基础参数配置 安装操作系统等操作请参见 Atlas 800 训练服务器 用户指南 型号9000 风冷 或 Atlas 800 训练服务器
  • Java——string[] 和List的区别

    一直对string 和List
  • JavaWeb之综合小项目

    案例需求 使用Java程序操作数据库 并把结果显示在jsp页面上 这里只做查询操作 增删改操作类似如此 使用工具 maven idea tomcat MySQL数据库 使用技术 javabean servlet jsp 准备阶段 第一步 使
  • 求全排列的数学方法(洛谷1088 火星人noip2004普及组第4题)

    人类终于登上了火星的土地并且见到了神秘的火星人 人类和火星人都无法理解对方的语言 但是我们的科学家发明了一种用数字交流的方法 这种交流方法是这样的 首先 火星人把一个非常大的数字告诉人类科学家 科学家破解这个数字的含义后 再把一个很小的数字
  • 实战wxPython:056 - GDI基本元素之颜色Colour

    GDI系统中的设备上下文包含一些基本元素 例如颜色 画刷 画笔或字体等等 wx Colour定义设备上下文中对象显示的颜色 wx Brush是一个用于填充区域的绘图工具 它用于绘制形状的背景 它有颜色和风格 wx Pen用于绘制形状的轮廓
  • 查询sql数据库中表占用的空间大小

    1 SQL统计数据 大量事务操作后可能不准 exec sp spaceused 表名 2 准确的表空间大小 但可能会花些统计时间 exec sp spaceused 表名 true 3 数据库大小查询 exec sp spaceused 4
  • 关于shiro doGetAuthorizationInfo授权方法和doGetAuthenticationInfo登陆认证方法的执行时机

    1 默认情况下不关闭shiro session 登陆时生成JESSIONID 执行doGetAuthorizationInfo的时机 1 subject hasRole admin 或 subject isPermitted admin 自
  • error: ‘FixedArray’ {aka ‘class ceres::internal::FixedArray<double, 3>’} has no member named ‘data’

    在使用g2o或者Ceres遇到以下问题 error FixedArray aka class ceres internal FixedArray
  • private static final Long serialVersionUID= 1L详解

    我们知道在对数据进行传输时 需要将其进行序列化 在Java中实现序列化的方式也很简单 可以直接通过实现Serializable接口 但是我们经常也会看到下面接这一行代码 private static final Long serialVer
  • R语言基础图形元素——坐标轴和网格线

    R语言基础图形元素 坐标轴和网格线 简介 1 坐标轴 2 网格线 参考书籍 简介 坐标轴为图中元素数值大小提供了参照 绘图时 时常需要实现坐标轴的个性化绘制 可以通过axis 函数实现 网格线是图形的一种辅助线 可以实现图中元素更加精确把控
  • R语言作图:坐标轴设置

    R语言作图 坐标轴设置 偷闲阁 2018 02 04 20 51 24 209654 收藏 359 分类专栏 R语言 可视化 文章标签 R 坐标轴 刻度 可视化 版权声明 本文为博主原创文章 遵循 C
  • 小白用Python抓取豆瓣高评分喜剧电影

    目的 抓取豆瓣高评分喜剧电影 导入所需的库 import requests 进行模拟浏览器进行发送请求 import json 导入JSON类型的库 不会导入库的话 请参考我的上一篇文章 上面有提及 小白如何抓取网页 进行确定URL和浏览器
  • 开发gitlab-reporting周报项目的总结

    一 方案设计 二 数据库设计 三 代码设计 从gitlab项目中输出每个成员的周报 事件触发webhook 接收webhook的server server解析webhook事件 做一个周报生成器 用gitlab的issues生成周报 功能
  • WebGL 视图矩阵、模型视图矩阵

    目录 立方体由三角形构成 视点和视线 视点 观察目标点和上方向 视点 观察目标点 上方向 在WebGL中 观察者的默认状态应该是这样的 视图矩阵程序 LookAtTriangles js 实际上 根据自定义的观察者状态 绘制观察者看到的景象
  • 【插件】谷歌浏览器插件visio在线打开vsdx文件

    下载地址
  • 【牛客C++入门】CPP10 判断成绩等级

    描述 键盘录入一个成绩 整数 判断并输出成绩的等级 如果用户输入成绩不合法 小于0或者大于100 则输出成绩不合法 90 100 优秀 80 89 良 70 79 中 60 69 及格 0 59 差 输入描述 输入学生的成绩 整数 输出描述
  • 最美应用API接口分析

    最美应用API接口分析 最美应用API接口分析一 请求版本列表1 1 API二 请求应用配置2 1 API2 2参数列表2 3 返回三 友盟更新3 1 API3 2参数列表3 3 返回四 appleStore应用信息4 1API4 2 返回
  • 发布npm包-简要记录

    1注册账号 注册npm账号 需要邮箱 激活npm账号 npm账号注册成功以后会收到邮件 邮件中有个链接 点进去进行激活 2创建项目 npm init 创建项目 name 命名规则 不能包含大写字母 空格及下滑线 version 创建时候默认
  • Shiro源码分析-初始化-SecurityManager

    源码分析的第一篇以SecurityManager的初始化为题 根据ini配置文件初始化shiro的代码主要为两段 解析ini文件为Ini对象 Factory