因为公司要求我对我司的框架的权限模块进行整理,因此最近看了Shiro这个框架的源码,里面有一些思想仍是很是值得学习的,记录一下java
官网提供了不少种权限的demo,提供web、spring支持、AspectJ、Guice等,因为笔者技术有限,那么我先从手洗的Spring开始说web
先送上官网的配置demospring
<!-- 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
为管理整个权限的对象apache
<!-- 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进行代理app
<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就是那个前缀jsp
filterChainDefinitions 这个过滤连比较重要了,首先说明一下,以匹配优先,也就是说,自上而下,若是上面的路径匹配上了,后面的就不会执行的了。 那么“=
”号左边的是请求链,固然这个匹配器能够改的,这些shiro都为咱们想得很周到,匹配了会采用filters下配的key对应的filter进行处理,可是呢,shiro只处理两种,这两种分别是,要么没有中括号,要么有一个中括号,下面就是解析结果ide
foo returned[0] == foo returned[1] == null foo[bar, baz] returned[0] == foo returned[1] == bar, baz
那么咱们如今知道怎么用了,接下来解读一下源码:学习
因为
ShiroFilterFactoryBean
是如今Spring中的FactoryBean
那么最后确定会调用getObject
方法,那么他最终仍是采用SecurityManager来建立一个Filter,建立Filter以前,有一个FilterChainManager,过滤连的一个管理者,那么这个东西里面默认是shiro的提供的Filter,除了默认的filter,他会添加咱们在xml配置的filter,而且在会在filterChainDefinitions
的时候进行解析,而且添加到FilterChainManager中进行管理ui
到目前为止,已经成功建立了一个SpringShiroFilter
因为SpringShiroFilter
继承了AbstractShiroFilter,那么最终会执行doFilterInternal方法,那么这个方法里面也执行了executeChain,这里就是执行这个过滤的入口 他里面采用了代理的关系,怎么说呢?
FilterChainResolver
就是作这个事情的,在建立Security的时候已经产生了,这个类就是产生FilterChain的,那么再给回去调用FilterChain.doFilter
那么咱们下面说一下他是怎么获取FilterChain的,首先他是依赖FilterChainManager的 那么来到这里就已经很明显了,因为FilterChainManager都把Filter准备好了,很明显,在它在Filter的时候已经添加了一个包装了一下,把解析的那些都放在里面了,那么匹配上了,直接获取出来,最后看下包装后是怎么执行的
那么整个过程大概就是这样子