shiro相关Filter

Posted OUYM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shiro相关Filter相关的知识,希望对你有一定的参考价值。

0前言

shiro中的filer是使用servlet中的filter接口扩展的,但是shiro代理了servlet 原声的filter,请求到了后会先执行shiro的filter,再执行原声的filter。

前面文章项目启动时shiro加载过程中介绍过,shiro只配置了shiroFilter一个拦截器入口,那么shiro是怎样执行内部那么多filter的?shiro内部的filter又是如何实现的呢?

带着上述两个问题,我们梳理下shiro的filter实现和工作流程

 

1shiro的filter实现

这里照搬一下zhangkaitao博客中的图。

 

 (1)Filter

servlet的filter,不熟悉的可以看一下servlet规范。

(2)AbstractFilter

shiro实现,主要用来配置FilterConfig,init()方法里提供了一个模板方法onFilterConfigSet()供子类实现。

(3)NameableFilter

给filter起名字的,如shiro自带的anon、authc,名字要求唯一,不然会有问题。

(4)OncePerRequestFilter

用于防止多次执行 Filter 的;也就是说一次请求只会走一次拦截器链;另外提供 enabled 属性,表示是否开启该拦截器实例,默认 enabled=true 表示开启,如果不想让某个拦截器工作,可以设置为 false 即可。可以简单看一下dofilter实现,源码107行

    public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
//首先检查一下有没有执行过这个filter,通过在request里面设置attribute实现
if ( request.getAttribute(alreadyFilteredAttributeName) != null ) { log.trace("Filter \'{}\' already executed. Proceeding without invoking this filter.", getName()); filterChain.doFilter(request, response); } else //noinspection deprecation
//在判断一下这个拦截器需不需要执行enable属性为true才需要执行 if (/* added in 1.2: */ !isEnabled(request, response) || /* retain backwards compatibility: */ shouldNotFilter(request) ) { log.debug("Filter \'{}\' is not enabled for the current request. Proceeding without invoking this filter.", getName());
//不需要执行就到连接器链的下一个拦截器 filterChain.doFilter(request, response); }
else { // Do invoke this filter... log.trace("Filter \'{}\' not yet executed. Executing now.", getName()); request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); try {
//重点,shiro的拦截器都走这个逻辑,这是一个模板方法,具体实现交给子类实现 doFilterInternal(request, response, filterChain); }
finally { // Once the request has finished, we\'re done and we don\'t // need to mark as \'already filtered\' any more. request.removeAttribute(alreadyFilteredAttributeName); } } }

OncePerRequestFilter算是一个比较重要的Filter实现,shiro的所有filter只有这一次dofilter实现。OncePerRequestFilter子类分成了两个分支:

一个是AdviceFilter,该类提供了Filter的Aop风格支持,并且shiro内部授权和验证的filter实现都是在这一分支。

一个是AbstractShiroFilter,也就是web.xml中配置的shiro入口filter。

 

todo

 

以上是关于shiro相关Filter的主要内容,如果未能解决你的问题,请参考以下文章

全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段

Shiro系列之Shiro+Spring MVC整合(Integration)

Shiro系列之Shiro+Spring MVC整合(Integration)

Shiro系列之Shiro+Spring MVC整合(Integration)

Shiro系列之Shiro+Spring MVC整合(Integration)

细说shiro之自定义filter