Shiro源码分析-初始化-SecurityManager
来源:互联网 发布:网络推广思维导图 编辑:程序博客网 时间:2024/05/16 09:26
源码分析的第一篇以SecurityManager的初始化为题。
根据ini配置文件初始化shiro的代码主要为两段:
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类构造方法:
classpathshiro-config.ini从类路径中查找ini配置urlhttp://....../shiro-config.ini从指定的url获取ini配置fileD:\shiro-config.ini从指定的文件路径获取ini配置3、对获取的资源输入流最终交给文本扫描器Scaner,执行过程代码片段:
至此,ini文件的解析已经完成,其ini中的内容已全部以map的形式存放在Ini实例中。
至于保存的结果是什么样的呢?以下面的一段配置为例:
二、由Ini实例构造SecurityManager对象
IniSecurityManagerFactory->IniFactorySupport->AbstractFactory->Factory
这里的getInstance方法由最上级的抽象类:org.apache.shiro.util.AbstractFactory提供,源码如下:
先阅读createDefaultInstance方法源码
类名称构造方法创建的默认对象DefaultSecurityManagerDefaultSubjectFactory,DefaultSubjectDAOSessionsSecurityManagerDefaultSessionManagerAuthorizingSecurityManagerModularRealmAuthorizerAuthenticatingSecurityManagerModularRealmAuthenticatorRealmSecurityManager无CachingSecurityManager无在上面的表格中已经清晰的描述了各个类所设置的默认对象,至于用途后面再讲解。
根据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);这里支持三种获取资源的方式:
classpathshiro-config.ini从类路径中查找ini配置urlhttp://....../shiro-config.ini从指定的url获取ini配置fileD:\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]#authenticatorauthenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticatorauthenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategyauthenticator.authenticationStrategy=$authenticationStrategysecurityManager.authenticator=$authenticatorIni的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的所有父类构造器的处理逻辑。
类名称构造方法创建的默认对象DefaultSecurityManagerDefaultSubjectFactory,DefaultSubjectDAOSessionsSecurityManagerDefaultSessionManagerAuthorizingSecurityManagerModularRealmAuthorizerAuthenticatingSecurityManagerModularRealmAuthenticatorRealmSecurityManager无CachingSecurityManager无在上面的表格中已经清晰的描述了各个类所设置的默认对象,至于用途后面再讲解。
0 0
- Shiro源码分析-初始化-SecurityManager
- Shiro源码之SecurityManager
- Shiro源码分析-初始化-Realm
- Shiro身份认证流程,securityManager源码解析
- shiro源码分析之shiroFilter初始化过程
- shiro securityManager结构
- Shiro详解之SecurityManager
- Shiro源码分析
- shiro认证授权源码分析
- shiro注解授权源码分析
- Shiro源码分析----认证流程
- Shiro源码分析----登录流程
- Shiro源码分析----授权流程
- Shiro源码分析----认证流程
- shiro配置报错No SecurityManager
- 2.详解SecurityManager(shiro权限管理门面)
- shiro报错No SecurityManager accessible
- 【Shiro权限管理】13. SecurityManager配置realms
- 带记忆功能的QSqlitter
- QT系列教程
- mysql常用函数
- android AppWidgetProvider讲解
- UITableView的常用方法
- Shiro源码分析-初始化-SecurityManager
- 数据库序列( SEQUENCE)的使用
- 广电总局发布TVOS2.0,首批63家成员单位(含乐视致新)
- for和forin区别
- vm硬盘及主板
- Json.NET读写Json文件(转)
- qt控件的使用
- 如何知道我在通知栏的展示的 Notification 被点击了?
- Alex 的 Hadoop 菜鸟教程: 第12课 Sqoop1 安装/导入/导出教程