由于公司要求我对我司的框架的权限模块进行整理,所以最近看了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
到目前为止,已经成功创建了一个SpringShiroFilterSpringShiroFilter
由于SpringShiroFilter
继承了AbstractShiroFilter,那么最终会执行doFilterInternal方法,那么这个方法里面也执行了executeChain,这里就是执行这个过滤的入口
FilterChainResolver
就是做这个事情的,在创建Security的时候已经产生了,这个类就是产生FilterChain的,那么再给回去调用FilterChain.doFilter
那么我们下面说一下他是怎么获取FilterChain的,首先他是依赖FilterChainManager的
那么来到这里就已经很明显了,由于FilterChainManager都把Filter准备好了,很明显,在它在Filter的时候已经添加了一个包装了一下,把解析的那些都放在里面了,那么匹配上了,直接获取出来,最后看下包装后是怎么执行的 那么整个过程大概就是这样子分析的不好勿喷,只是做一个学习的记录
来源:oschina
链接:https://my.oschina.net/u/1983041/blog/735984