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博客中的图。

shiro相关Filter

 

 (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 session超时


下一篇:shiro和springmvc配置静态资源过滤