文档章节

Shiro源码分析之ShiroFilterFactoryBean

0909
 0909
发布于 2016/08/12 10:17
字数 950
阅读 246
收藏 8
点赞 1
评论 0

一、Spring 的DelegatingFilterProxy如何发现 Shiro 的ShiroFilterFactoryBean

简单的回顾一下,web.xml配置中的Spring DelegatingFilterProxy 的这个Filter是如何找到WebApplicationcontext 配置(Spring.xml配置文件)中的ShiroFilterFactoryBean。

web.xml配置:

<filter>
        <filter-name>securityFilter</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
</filter>

其实际是通过上面web.xml文件中的<filter-name>securityFilter</filter-name>,securityFilter去找到spring-context.xml配置文件中类型为Filter,id为securityFilter的Bean。

spring-context.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <!-- 此处省略部分配置-->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 此处省略部分配置-->
		<property name="securityManager" ref="securityManager" />
		<property name="unauthorizedUrl" value="/" />
		<property name="filters">
			<map>
				<entry key="formAuthc" value-ref="formAuthc" />
			</map>
		</property>
		<property name="filterChainDefinitions">
			<value>
				/static/** = anon
				/login = formAuthc
				/logout = logout
			</value>
		</property>
	</bean>
</beans>

详解的源码分析可见http://my.oschina.net/u/1421030/blog/729706

二、Shiro 的ShiroFilterFactoryBean源码分析

前一节说到Spring的DelegatingFilterProxy是通过在Spring的配置文件中找到类型为Filter且id与web.xml文件其filter-name一致的Bean来发现ShiroFilterFactoryBean的。 但我们会发现ShiroFilterFactoryBean好像没有实现Filter接口,是不是有什么问题呢??

ShiroFilterFactoryBean 声明代码:

public class ShiroFilterFactoryBean implements FactoryBean, BeanPostProcessor... 

其实ShiroFilterFactoryBean 实现了FactoryBean接口正式在这里有我们想要的。 ApplicationContext的对待FactoryBean类型的Bean,通过配置文件的中Bean的id得到的其实是FactoryBean#getObject方法对应类型的Bean详细可见http://my.oschina.net/u/1421030/blog/729908。 现在来看看ShiroFilterFactoryBean 的getObject方法的具体实现吧。

ShiroFilterFactoryBean #getObject代码:

public Object getObject() throws Exception {
        if (instance == null) {
            instance = createInstance();
        }
        return instance;
    }

再看看

ShiroFilterFactoryBean #createInstance代码:

protected AbstractShiroFilter createInstance() throws Exception {
        logdebug("Creating Shiro Filter instance.");
        SecurityManager securityManager = getSecurityManager();
        //省略部分代码
        //创建FilterChain管理器,会将Shiro默认的Filter加入进来,同时将配置文件中的Filter加进来
        FilterChainManager manager = createFilterChainManager();
        PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
        chainResolver.setFilterChainManager(manager);
        return new SpringShiroFilter((WebSecurityManager) securityManager, chainResolver);
    }

可以看到createInstance方法返回的是一个AbstractShiroFilter 类对象,而该类的父类实际实现了Filter接口。 再来看看createInstance方法中最重要的createFilterChainManager

ShiroFilterFactoryBean #createFilterChainManager代码:

  protected FilterChainManager createFilterChainManager() {
        /*创建默认的FilterChainManager,创建时会将anon, authc, authcBasic等Filter加入*/
        DefaultFilterChainManager manager = new DefaultFilterChainManager();
        Map<String, Filter> defaultFilters = manager.getFilters();
        //apply global settings if necessary:
        for (Filter filter : defaultFilters.values()) {
            applyGlobalPropertiesIfNecessary(filter);
        }
       //得到Spring配置文件中设置给ShiroFilterFactoryBean 的Filter
        Map<String, Filter> filters = getFilters();
        /*省略部分代码,此处将Spring设置给ShiroFilterFactoryBean 的Filter
         加入DefaultFilterChainManager 
        */
        /*得到配置文件中ShiroFilterFactoryBean 对应的filterChainDefinitions属性设置的键值对
         最终能根据vaule找到其对应的其实类Filter的全名与对应的FilterConfig信息
        */
        Map<String, String> chains = getFilterChainDefinitionMap();
        if (!CollectionUtils.isEmpty(chains)) {
            for (Map.Entry<String, String> entry : chains.entrySet()) {
                String url = entry.getKey();
                String chainDefinition = entry.getValue();
                manager.createChain(url, chainDefinition);
            }
        }
        return manager;
    }

先看看 DefaultFilterChainManager manager = new DefaultFilterChainManager()

DefaultFilterChainManager构造函数代码

 public DefaultFilterChainManager() {
        this.filters = new LinkedHashMap<String, Filter>();
        this.filterChains = new LinkedHashMap<String, NamedFilterList>();
       //加入Shiro中默认的Filter
       addDefaultFilters(false);
    }

DefaultFilterChainManager#addDefaultFilters代码

protected void addDefaultFilters(boolean init) {
        for (DefaultFilter defaultFilter : DefaultFilter.values()) {
            addFilter(defaultFilter.name(), defaultFilter.newInstance(), init, false);
        }
    }

DefaultFilter代码

public enum DefaultFilter {
    anon(AnonymousFilter.class),
    authc(FormAuthenticationFilter.class),
    authcBasic(BasicHttpAuthenticationFilter.class),
    logout(LogoutFilter.class),
    //省略部分代码
}

到这里终于看到了为什么我们可在spring-context.xml中的ShiroFilterFactoryBean定义中使用anon, authc,authcBasic等去设置filterChainDefinitions啦。 spring-context.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
    <!-- 此处省略部分配置-->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- 此处省略部分配置-->
		<property name="securityManager" ref="securityManager" />
		<property name="unauthorizedUrl" value="/" />
		<property name="filters">
			<map>
				<entry key="formAuthc" value-ref="formAuthc" />
			</map>
		</property>
		<property name="filterChainDefinitions">
			<value>
				/static/** = anon
				/login = formAuthc
				/logout = logout
			</value>
		</property>
	</bean>
</beans>

下面一些过程后面的文章分析。

© 著作权归作者所有

共有 人打赏支持
0909
粉丝 22
博文 16
码字总数 25047
作品 0
无锡
shiro登录流程

ShiroFilter Shiro提供了与Web集成的支持,其通过一个ShiroFilter入口来拦截需要安全控制的URL,然后进行相应的控制,ShiroFilter类似于如Strut2/SpringMVC这种web框架的前端 其是安全控制的...

嘿嘿!! ⋅ 2016/10/20 ⋅ 0

Spring与Shiro整合源码分析

Spring与Shiro整合是通过在web.xml里面配置过滤器: 然后我们在apllicationContext.xml里面配置如下的ShiroFilterFactoryBean就可以了 为什么这样配置就可以了?我们并没有在web.xml配置shi...

zpassion ⋅ 2016/09/14 ⋅ 0

一步一步教你用shiro——1引入shiro框架

一步一步教你用shiro——1引入shiro框架 一步一步教你用shiro——2配置并自定义realm 一步一步教你用shiro——3配置并自定义sessionManager 一步一步教你用shiro——4配置并自定义sessionDa...

肥肥小浣熊 ⋅ 04/30 ⋅ 0

Java权限框架Shiro过滤连源码解读

由于公司要求我对我司的框架的权限模块进行整理,所以最近看了Shiro这个框架的源码,里面有一些思想还是非常值得学习的,记录一下 入口 官网提供了很多种权限的demo,提供web、spring支持、A...

小彬彬_ ⋅ 2016/08/22 ⋅ 1

ShiroFilterFactoryBean源码及阻截原理深入分析

ShiroFilterFactoryBean源码及拦截原理深入分析 本篇文章篇幅比较长,但是细看下去相信对学习Shiro应该会有帮助。好了,闲话不多说,直接进入正题: Shiro提供了与Web集成的支持,其通过一个...

HelloRookie ⋅ 2016/10/09 ⋅ 0

Spring DelegatingFilterProxy 源码分析

在web项目,利用Spirng 管理权限框架时,不管权限框架使用的是Shiro还是SpringSecucrity在web.xml文件中都有一个名org.springframework.web.filter.DelegatingFilterProxy 的Filter。配置如下...

0909 ⋅ 2016/08/08 ⋅ 0

ShiroFilterFactoryBean源码及拦截原理深入分析

本篇文章篇幅比较长,但是细看下去相信对学习Shiro应该会有帮助。好了,闲话不多说,直接进入正题: Shiro提供了与Web集成的支持,其通过一个入口来拦截需要安全控制的URL,然后进行相应的控...

Geek-Tom ⋅ 2016/08/23 ⋅ 0

springboot和shiro整合

虽然网上一大堆这方面的文章,可是自己去整合还是会遇到这样那样的问题。今天写出来等待和我一样遇到相同问题的人看见。 首先明白一点springboot之后,web.xml配置基本上就是用不上了。那么,...

hyssop ⋅ 2016/10/21 ⋅ 0

自己的研究shiro框架的感悟1

首先在配置shiro框架时,由spring托管shiro。由spring框架中的DelegatingFilterProxy类来代理shiro框架中的ShiroFilterFactoryBean类,这样spring和shiro就有建立了关系。 web.xml文件中配置...

HelloRookie ⋅ 2016/10/16 ⋅ 0

dubbo接口对象传递

项目里面需要用springboot+dubbo+shiro做一个权限服务端,现在想要把Shiro中的ShiroFilterFactoryBean作为一个返回值供消费端使用,目前我在项目里面新建了一个bean继承ShiroFilterFactoryBea...

lgx7410 ⋅ 2017/08/16 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

C++内存映射文件居然是这样?!

内存映射文件大家都时不时听过,但它到底是个什么?赶紧来看看吧 内存映射文件到底是干嘛的呢?让我们先来思考下面几个问题: 如果您想读的内容大于系统分配的内存块怎么办?如果您想搜索的字...

柳猫 ⋅ 30分钟前 ⋅ 0

MySQL 数据库设计总结

规则1:一般情况可以选择MyISAM存储引擎,如果需要事务支持必须使用InnoDB存储引擎。 注意:MyISAM存储引擎 B-tree索引有一个很大的限制:参与一个索引的所有字段的长度之和不能超过1000字节...

OSC_cnhwTY ⋅ 今天 ⋅ 0

多线程(四)

线程池和Exector框架 什么是线程池? 降低资源的消耗 提高响应速度,任务:T1创建线程时间,T2任务执行时间,T3线程销毁时间,线程池没有或者减少T1和T3 提高线程的可管理性。 线程池要做些什...

这很耳东先生 ⋅ 今天 ⋅ 0

使用SpringMVC的@Validated注解验证

1、SpringMVC验证@Validated的使用 第一步:编写国际化消息资源文件 编写国际化消息资源ValidatedMessage.properties文件主要是用来显示错误的消息定制 [java] view plain copy edit.userna...

瑟青豆 ⋅ 今天 ⋅ 0

19.压缩工具gzip bzip2 xz

6月22日任务 6.1 压缩打包介绍 6.2 gzip压缩工具 6.3 bzip2压缩工具 6.4 xz压缩工具 6.1 压缩打包介绍: linux中常见的一些压缩文件 .zip .gz .bz2 .xz .tar .gz .tar .bz2 .tar.xz 建立一些文...

王鑫linux ⋅ 今天 ⋅ 0

6. Shell 函数 和 定向输出

Shell 常用函数 简洁:目前没怎么在Shell 脚本中使用过函数,哈哈,不过,以后可能会用。就像java8的函数式编程,以后获取会用吧,行吧,那咱们简单的看一下具体的使用 Shell函数格式 linux ...

AHUSKY ⋅ 今天 ⋅ 0

单片机软件定时器

之前写了一个软件定时器,发现不够优化,和友好,现在重写了 soft_timer.h #ifndef _SOFT_TIMER_H_#define _SOFT_TIMER_H_#include "sys.h"typedef void (*timer_callback_function)(vo...

猎人嘻嘻哈哈的 ⋅ 今天 ⋅ 0

好的资料搜说引擎

鸠摩搜书 简介:鸠摩搜书是一个电子书搜索引擎。它汇集了多个网盘和电子书平台的资源,真所谓大而全。而且它还支持筛选txt,pdf,mobi,epub、azw3格式文件。还显示来自不同网站的资源。对了,...

乔三爷 ⋅ 今天 ⋅ 0

Debian下安装PostgreSQL的表分区插件pg_pathman

先安装基础的编译环境 apt-get install build-essential libssl1.0-dev libkrb5-dev 将pg的bin目录加入环境变量,主要是要使用 pg_config export PATH=$PATH:/usr/lib/postgresql/10/bin 进......

玛雅牛 ⋅ 今天 ⋅ 0

inno安装

#define MyAppName "HoldChipEngin" #define MyAppVersion "1.0" #define MyAppPublisher "Hold Chip, Inc." #define MyAppURL "http://www.holdchip.com/" #define MyAppExeName "HoldChipE......

backtrackx ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部