Shiro的过滤链设计机制

1.一、过滤器种类

在shiro中,除过登录认证操作,最核心的就属一些列过滤器

shiro过滤器以及对应的类:过滤器

二、过滤器详解

以authc过滤器为例,对应的处理器类是FormAuthenticationFilter

1. 继承关系及结构

authc继承关系:

1.AbstractFilter > 2.NameableFilter > 3.OncePerRequestFilter > 4.AdviceFilter > 5.PathMatchingFilter > 6.AccessControlFilter > 7.AuthenticationFilter > 8.AuthenticatingFilter > 9.FormAuthenticationFilter

2. filter过滤器简介

tomcat中的自定义过滤器必需实现Filter接口,过滤器的实现方法为Filter中的

doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain),如果一个请求被该过滤器拦截,想要到达用户最后请求的地址,那么一定得有:filterChain.doFilter(request, response);这个方法的调用,表示通过过滤,请求可以到达用户的请求地址。否则用户的请求地址不会被调用,用户的请求被过滤器拦截

3. shiro过滤器分析

3.1 AbstractFilter

源码:

package org.apache.shiro.web.servlet;

public abstract class AbstractFilter extends ServletContextSupport implements Filter {

    private static final transient Logger log = LoggerFactory.getLogger(AbstractFilter.class);

    protected FilterConfig filterConfig;

    public AbstractFilter() {

    }

    ... ...

 }

1

2

3

4

5

6

7

8

从源码中可以看到AbstractFilter 是个抽象类,直接实现了Filter接口

Filter.class

AbstractFilter .class

总结:AbstractFilter只做了一些基本的初始化,并没有过多的逻辑在里面,没有实现Filter中的doFilter方法

3.2 NameableFilter

大致意思是:允许通过getName和setName方式给过滤器命名。如果没有给该过滤器命名,那么默认将会使用web.xml中给定的名称(FilterConfiger的filterName)

总结:NameableFilter是用于给过滤器命名使用的,没有实现Filter中的doFilter方法

3.3 OncePerRequestFilter

大致意思是:filter的基类(就是真正实现了Filter中的doFilter方法的类),它用来保证在每个servlet容器上,第个请求都只会被过滤一次,不会重复过滤。

通过getAlreadyFilteredAttributeName()方法来鉴别请求是否已经被过滤过。默认的实现基于具体过滤的实例名称。

doFilter()具体实现逻辑:

判断过滤器是否已经执行过过滤,如果执行过,调用filterChain.doFilter(request, response)直接放行,不再重复执行该过滤器的处理逻辑,直接走下一个过滤器或者通过该过滤进入到实际请求方法中。

判断过滤器是否开启,该类有个成员变量eabled,默认为true(注释给的解释是大多数的过滤器都是希望开启的,所以默认值为true),过滤器为开启状态,如果该过滤器没有被开启中,也同上面的逻辑一样,直接调用filterChain.doFilter(request, response)走下一个过滤器或者通过该过滤进入到实际请求方法中。

分为三步:

(1)设置一个已经执行过滤器的属性名称在request中,默认为TRUE

(2)调用doFilterInternal方法,执行真正的过滤器处理逻辑

(3)这个过滤器处理完后,将过滤器的属性名称从request中移出。这样如果程序执行到第2步,过滤又被调用了,它将会走到第一个if中,直接略过这个过滤器的处理,这样就保证了,每个过滤器在处理一个请求的时候只会被执行一次

总结:OncePerRequestFilter提供了一个实际处理过滤业务的方法doFilterInternal,并且保证每个请求只会被该过滤器过滤一次。

3.4 AdviceFilter

大致意思是:类似于开启了AOP环绕通知,提供了preHandle,postHandle和afterCompletion这三个方法

其过滤逻辑为:doFilterInternal方法

executeChain方法中的实现为:chain.doFilter(request, response);所以如果preHandle方法返回false,则说明过滤器不会执行chain.doFilter,意味着请求被拦截掉了,不会进入到用户请求的地址上去。如果为true,表示过滤器放行了过滤的逻辑通过

然后会执行postHandle方法(该类中的postHandle方法为空实现)

最后会执行一个,这个方法用于对一些异常进行处理(目前也是空实现)

总结:AdviceFilter提供了类似于AOP环绕通知式的编程方式,其处理拦截的逻辑是在preHandle方法中完成的。preHandle方法返回true和false代表了通过过滤,请求可以到达用户的请求地址和过滤器拦截掉了用户的请求

3.5 PathMatchingFilter

大致意思是:这个过滤器会处理指定的请求路径,和对其它路径的请求放行。

比如:如果配置如下拦截,/hello=authc,这就意味着,请用户请求/hello时,这时的authc过滤就会对这个请求拦截并进行过滤逻辑处理。如果一个用户请求是/world,则不会对此请求过滤

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值