servlet的初始化会触发核心过滤器的创建:

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

在createInstance方法中会调用

FilterChainManager manager = createFilterChainManager();

protected FilterChainManager createFilterChainManager() {

    DefaultFilterChainManager manager = new DefaultFilterChainManager();
Map<String, Filter> defaultFilters = manager.getFilters();
//apply global settings if necessary:
for (Filter filter : defaultFilters.values()) {
applyGlobalPropertiesIfNecessary(filter);
} //Apply the acquired and/or configured filters:
Map<String, Filter> filters = getFilters();
if (!CollectionUtils.isEmpty(filters)) {
for (Map.Entry<String, Filter> entry : filters.entrySet()) {
String name = entry.getKey();
Filter filter = entry.getValue();
applyGlobalPropertiesIfNecessary(filter);
if (filter instanceof Nameable) {
((Nameable) filter).setName(name);
}
//'init' argument is false, since Spring-configured filters should be initialized
//in Spring (i.e. 'init-method=blah') or implement InitializingBean:
manager.addFilter(name, filter, false);
}
} //build up the chains:
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默认构造器会填充所有默认的filter,为11个。

public DefaultFilterChainManager() {
this.filters = new LinkedHashMap<String, Filter>();
this.filterChains = new LinkedHashMap<String, NamedFilterList>();
addDefaultFilters(false);
} protected void addDefaultFilters(boolean init) {
for (DefaultFilter defaultFilter : DefaultFilter.values()) {
addFilter(defaultFilter.name(), defaultFilter.newInstance(), init, false);
}
}

当你有自己的实现时,如扩展了FormAuthenticationFilter,key为authc,增加了一个check和ssoAuthc。

<property name="filters">
<util:map>
<entry key="authc" value-ref="formAuthenticationFilter" />
<entry key="check" value-ref="authcFilter"/>
<entry key="ssoAuthc" value-ref="MyShiroCasFilter"/>
</util:map>
</property>

这时ShiroFilterFactoryBean维护这3个。

createFilterChainManager方法会把默认的给覆盖掉,因为自定义和默认的key均为authc。

public void addFilter(String name, Filter filter, boolean init) {
addFilter(name, filter, init, true);
} protected void addFilter(String name, Filter filter, boolean init, boolean overwrite) {
Filter existing = getFilter(name);
if (existing == null || overwrite) {
if (filter instanceof Nameable) {
((Nameable) filter).setName(name);
}
if (init) {
initFilter(filter);
}
this.filters.put(name, filter);
}
}

操作完后DefaultFilterChainManager维护13个(覆盖1个,新增2个)

然后构造Map

/images/** = anon
/css/** = anon
/resources/** = anon
/js/** = anon
/static/** = anon
/logout.do = anon
/rest/** = anon
/** = check,authc

如上面的map转换成filterChains之后,key为”/**”的value是一个包含两个过滤器的NamedFilterList(一个名叫check 一个名为authc)。

“/**” -> ” size = 2”

当请求过来时,PathMatchingFilterChainResolver的getChain来获取需要的过滤器链,这个会匹配之前保存的Map集合,匹配上就立马返回这个代理的过滤器链(ProxiedFilterChain)。

然后就是执行代理过滤器链:

整个过程就是先解析配置文件中的映射关系,转化成内存中的Map映射,当一个请求过来时, 先被核心过滤器拦截,然后根据匹配规则构造代理过滤器链,这个代理过滤器链包含了需要走的过滤器。

最后执行代理过滤器链的doFilter方法:遍历需要执行的匹配上的过滤器,挨个执行,但是自定义和默认的过滤器都是传的ProxiedFilterChain本身,所以放行的时候又会绕回ProxiedFilterChain的doFilter方法,这样就形成了逻辑上的链,shiro自己的链式执行。

匹配的过滤器执行完后,才会放行到servlet的过滤器链继续执行。

Shiro过滤器的维护与匹配执行的更多相关文章

  1. shiro过滤器详解分析

    (原) shiro最核心的2个操作,一个是登录的实现,一就是过滤器了.登录有时间再补录说明,这里分析下shiro过滤器怎样玩的. 1.目标 这里会按如下顺序逐一看其实原理,并尽量找出其出处. 先看一下 ...

  2. Shiro第四篇【Shiro与Spring整合、快速入门、Shiro过滤器、登陆认证】

    Spring与Shiro整合 导入jar包 shiro-web的jar. shiro-spring的jar shiro-code的jar 快速入门 shiro也通过filter进行拦截.filter拦 ...

  3. Shiro【授权、整合Spirng、Shiro过滤器】

    前言 本文主要讲解的知识点有以下: Shiro授权的方式简单介绍 与Spring整合 初始Shiro过滤器 一.Shiro授权 上一篇我们已经讲解了Shiro的认证相关的知识了,现在我们来弄Shiro ...

  4. Spring Boot环境下自定义shiro过滤器会过滤所有的url的问题

    在配置shiro过滤器时增加了自定义的过滤器,主要是用来处理未登录状态下返回一些信息 //自定义过滤器 Map<String, Filter> filtersMap = new Linke ...

  5. servlet过滤器实现维护项目

    最近公司需要系统维护,提出要建一个维护系统,要求: 1.访问公司域名跳到系统首页 2.点击首页的任意按钮给出维护提示信息 3.用户访问之前收藏的任意系统链接跳转到首页 下面介绍下用过滤器实现上述需求 ...

  6. web项目中的监听器,过滤器以及自定义servlet的执行顺序

    可以看到web容器一启动就会实例化监听器的contextInitialized(ServletContextEvent event)方法,然后是过滤器的init()方法,最后在用户访问web应用的 时 ...

  7. [Codeforces 1027 F] Session in BSU [并查集维护二分图匹配问题]

    题面 传送门 思路 真是一道神奇的题目呢 题目本身可以转化为二分图匹配问题,要求右半部分选择的点的最大编号最小的一组完美匹配 注意到这里左边半部分有一个性质:每个点恰好连出两条边到右半部分 那么我们可 ...

  8. Spring Boot 自定义 Shiro 过滤器,无法使用 @Autowired 解决方法

    在 Spring Boot 中集成 Shiro,并使用 JWT 进行接口认证. 为了统一对 Token 进行过滤,所以自定义了一个 JwtTokenFilter 过滤器. 期间遇到了以下几个问题,这里 ...

  9. shiro过滤器机制

    shiro内置过滤器介绍 https://blog.csdn.net/qq_35608780/article/details/71703197 Shiro的Filter机制详解---源码分析 http ...

随机推荐

  1. C11工具类:时间处理

    C++11提供时间管理类,包括三种类型:时间间隔duration,时钟clocks,时间点time point. 1.记录时常的duration 1.1 原型 duration表示一段时间间隔,用来记 ...

  2. C语言数据结构-栈

    一.栈的定义 栈(statck)这种数据结构在计算机中是相当出名的.栈中的数据是先进后出的(First In Last Out, FILO).栈只有一个出口,允许新增元素(只能在栈顶上增加). 移出元 ...

  3. 【CodeForces】582 C. Superior Periodic Subarrays

    [题目]C. Superior Periodic Subarrays [题意]给定循环节长度为n的无限循环数列,定义(l,s)表示起点为l的长度为s的子串,(l,s)合法要求将子串从该起点开始以s为循 ...

  4. pcap的安装

    pcap,即 packet capture library 抓包库,这个抓包库给抓包系统提供了一个高层次的接口.所有网络上的数据包,甚至是那些发送给其他主机的,通过这种机制,都是可以捕获的.它也支持把 ...

  5. linux命令行todo列表管理工具Taskwarrior介绍

    Taskwarrior 是一款在命令行下使用的TODO列表管理工具,或者说任务管理工具,灵活,快速,高效. 安装 在ubuntu 14.04 中,可从官方仓库安装task软件包 sudo apt-ge ...

  6. ThinkPHP5 模型 - 事务支持

    使用事务之前,先确保数据库的存储引擎支持事务操作. MyISAM:不支持事务,主要用于读数据提高性能 InnoDB:支持事务.行级锁和并发 Berkeley DB:支持事务 ThinkPHP5 使用事 ...

  7. 工具===代替cmd的conemu设置

    conemu设置 Win+Alt+P进入设置界面,字体设置: 隐藏右上角菜单和窗口标题. (Ctrl + ~ 隐藏/显示terminal) 设置背景图片 避免误操作,关闭/新建确认 设置win+w默认 ...

  8. python基础===python os.path模块

    os.path.abspath(path) #返回绝对路径 os.path.basename(path) #返回文件名 os.path.commonprefix(list) #返回list(多个路径) ...

  9. Redis 主从部署

    Redis 主从部署 http://www.xuchanggang.cn/archives/978.html

  10. 12-4 NSString

    原文:http://rypress.com/tutorials/objective-c/data-types/nsstring NSString 在本教程的内容可能我们已经看到过很多次了,NSStri ...