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

不羁的心 提交于 2020-03-02 18:38:41

由于公司要求我对我司的框架的权限模块进行整理,所以最近看了Shiro这个框架的源码,里面有一些思想还是非常值得学习的,记录一下

入口

官网提供了很多种权限的demo,提供web、spring支持、AspectJ、Guice等,由于笔者技术有限,那么我先从手洗的Spring开始说


Spring

先送上官网的配置demo

spring shiro xml

<!-- Define the realm you want to use to connect to your back-end security datasource: -->
<bean id="myRealm" class="...">
...
</bean>

<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
    <!-- Single realm app.  If you have multiple realms, use the 'realms' property instead. -->
    <property name="realm" ref="myRealm"/>
</bean>

首先说一下realm,他是获取一个用户的信息,其中里面包括权限,角色等信息,securityManager为管理整个权限的对象


web.xml

<!-- The filter-name matches name of a 'shiroFilter' bean inside applicationContext.xml -->
<filter>
    <filter-name>shiroFilter</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>

...

<!-- Make sure any request you want accessible to Shiro is filtered. /* catches all -->
<!-- requests.  Usually this filter mapping is defined first (before all others) to -->
<!-- ensure that Shiro works in subsequent filters in the filter chain:             -->
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

DelegatingFilterProxy为提供的filter类,所以它肯定会找一个代理的实际对象,在这里能,他会找filter-name的bean id进行代理


applicationContext.xml

<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
    <property name="securityManager" ref="securityManager"/>
    <property name="loginUrl" value="/login.jsp"/>
    <property name="successUrl" value="/home.jsp"/>
    <property name="filters">
        <util:map>
            <entry key="anAlias" value-ref="someFilter"/>
        </util:map>
    </property>
    <property name="filterChainDefinitions">
        <value>
            # some example chain definitions:
            /admin/** = authc, roles[admin]
            /docs/** = authc, perms[document:read]
            /** = authc
            # more URL-to-FilterChain definitions here
        </value>
    </property>
</bean>

shiroFilter代理的就是这个filter,那么我们来分析一下,了解过shiro的就不说简单的了,就特别说一下filters和filterChainDefinitions


  • filters shiro已经提供了默认的filter的了,所以你很多时候都可以看到一些例如,authc、rols、perms、anon等等这样的配置前缀,那么这些都说shiro自己默认提供的 当然你可以通过自己实现Filter接口然后配置到filters中,key就是那个前缀

  • filterChainDefinitions 这个过滤连比较重要了,首先说明一下,以匹配优先,也就是说,自上而下,如果上面的路径匹配上了,后面的就不会执行的了。 那么“=”号左边的是请求链,当然这个匹配器可以改的,这些shiro都为我们想得很周到,匹配了会采用filters下配的key对应的filter进行处理,但是呢,shiro只处理两种,这两种分别是,要么没有中括号,要么有一个中括号,下面就是解析结果

    foo
    returned[0] == foo returned[1] == null
    
    foo[bar, baz]
    returned[0] == foo returned[1] == bar, baz
    

那么我们现在知道怎么用了,接下来解读一下源码:


解读源码

ShiroFilterFactoryBean

由于ShiroFilterFactoryBean是现在Spring中的FactoryBean那么最后肯定会调用getObject方法,那么他最终还是采用SecurityManager来创建一个Filter,创建Filter之前,有一个FilterChainManager,过滤连的一个管理者,那么这个东西里面默认是shiro的提供的Filter,除了默认的filter,他会添加我们在xml配置的filter,并且在会在filterChainDefinitions的时候进行解析,并且添加到FilterChainManager中进行管理

FilterChainManager

到目前为止,已经成功创建了一个SpringShiroFilter

SpringShiroFilter

由于SpringShiroFilter继承了AbstractShiroFilter,那么最终会执行doFilterInternal方法,那么这个方法里面也执行了executeChain,这里就是执行这个过滤的入口

他里面采用了代理的关系,怎么说呢? FilterChainResolver就是做这个事情的,在创建Security的时候已经产生了,这个类就是产生FilterChain的,那么再给回去调用FilterChain.doFilter

那么我们下面说一下他是怎么获取FilterChain的,首先他是依赖FilterChainManager的

那么来到这里就已经很明显了,由于FilterChainManager都把Filter准备好了,很明显,在它在Filter的时候已经添加了一个包装了一下,把解析的那些都放在里面了,那么匹配上了,直接获取出来,最后看下包装后是怎么执行的

那么整个过程大概就是这样子

分析的不好勿喷,只是做一个学习的记录

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!