- 浏览: 1202268 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
insistboy:
写的太棒了,受不了
WebLogic11g-创建域(Domain) -
goldyeah:
厉害了 困扰我大半个月的问题解决了 谢谢博主
WebLogic11g-单双向SSL配置(以Springside3为例) -
zy315351965:
404伤不起
开源流程引擎Snaker -
nannan408:
双向的时候谷歌提示“不接受您的登录证书,或者您可能没有提供登录 ...
WebLogic11g-单双向SSL配置(以Springside3为例) -
一颗赛艇:
不成功啊。启动有问题 <Security> < ...
WebLogic11g-单双向SSL配置(以Springside3为例)
通过前面Spring Security提供的各种Filter的分析,大体上知道每个Filter具体的用途了。
Spring Security一共提供了20个Filter,我目前只分析了13个(如果http的auto-config="true",那默认的filter列表都包含在这13个里面了),另外7个在后面的源码分析中碰到时会逐个讲解。
在分析http标签时,已经提到filter排序的问题了,但是没有深入。
现在再回头看filter是如何排序的。下面的代码片段截取自HttpSecurityBeanDefinitionParser类,
细心的同学会发现httpBldr.getFilters()、authBldr.getFilters()两个方法返回的就是OrderDecorator对象的集合列表。并且OrderDecorator对象已经将filter与SecurityFilters中的order关联了起来
顺便看一下创建自定义过滤器部分
这里用到三个重要的与排序相关的类及枚举,分别是OrderDecorator、OrderComparator以及SecurityFilters枚举
首先看SecurityFilters枚举定义
由此可见,该类维护了Spring Security中每个filter的顺序
接着看OrderDecorator类。这个类实现org.springframework.core.Ordered接口
OrderComparator类的路径是org.springframework.core.OrderComparator,实际上是spring core包的一个比较器,可以顺便看下OrderComparator源码。下面截取的只是部分核心代码
通过以上的分析,可以总结如下
1.由SecurityFilters维持位置order
2.由OrderDecorator维持filter与order的对应关系
3.由OrderComparator负责比较OrderDecorator的先后顺序
附上默认的过滤器顺序列表
以上标注红色的都已经分析完毕
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
可以自定义 LogoutFilter不。因为我这边session信息是写到缓存里面的。当登出的时候,需要将缓存里面的权限信息删除。
在logoutfilter前面增加一个自定义过滤器清除缓存的就行了
谢谢,我想到了另外一个思路,应用这边都不需要做特别的配置。
我增加一个监听器,来保存和移除缓存中权限信息,一个过滤器,来恢复当服务器宕机重启或者切换时的权限信息。
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
可以自定义 LogoutFilter不。因为我这边session信息是写到缓存里面的。当登出的时候,需要将缓存里面的权限信息删除。
在logoutfilter前面增加一个自定义过滤器清除缓存的就行了
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
可以自定义 LogoutFilter不。因为我这边session信息是写到缓存里面的。当登出的时候,需要将缓存里面的权限信息删除。
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
Spring Security一共提供了20个Filter,我目前只分析了13个(如果http的auto-config="true",那默认的filter列表都包含在这13个里面了),另外7个在后面的源码分析中碰到时会逐个讲解。
在分析http标签时,已经提到filter排序的问题了,但是没有深入。
现在再回头看filter是如何排序的。下面的代码片段截取自HttpSecurityBeanDefinitionParser类,
//定义未排序filter集合。该集合中的对象为OrderDecorator实例。 List<OrderDecorator> unorderedFilterChain = new ArrayList<OrderDecorator>(); //添加http、认证相关的filter集合 unorderedFilterChain.addAll(httpBldr.getFilters()); unorderedFilterChain.addAll(authBldr.getFilters()); //定义RequestCacheAwareFilter过滤器,并添加到unorderedFilterChain中 BeanDefinition requestCacheAwareFilter = new RootBeanDefinition(RequestCacheAwareFilter.class); requestCacheAwareFilter.getPropertyValues().addPropertyValue("requestCache", authBldr.getRequestCache()); unorderedFilterChain.add(new OrderDecorator(requestCacheAwareFilter, REQUEST_CACHE_FILTER)); //添加自定义filter unorderedFilterChain.addAll(buildCustomFilterList(element, pc)); //根据排序规则进行排序 Collections.sort(unorderedFilterChain, new OrderComparator()); //检查每个filter与前一个filter的位置是否相同 //这里的检查主要是防止自定义filter直接配置position属性,造成与默认的filter产生order冲突 checkFilterChainOrder(unorderedFilterChain, pc, source); //重新定义filterChain,把经过排序的filter依次添加到filterChain集合中 List<BeanMetadataElement> filterChain = new ManagedList<BeanMetadataElement>(); for (OrderDecorator od : unorderedFilterChain) { filterChain.add(od.bean); }
细心的同学会发现httpBldr.getFilters()、authBldr.getFilters()两个方法返回的就是OrderDecorator对象的集合列表。并且OrderDecorator对象已经将filter与SecurityFilters中的order关联了起来
unorderedFilterChain.addAll(httpBldr.getFilters()); unorderedFilterChain.addAll(authBldr.getFilters());
顺便看一下创建自定义过滤器部分
List<OrderDecorator> buildCustomFilterList(Element element, ParserContext pc) { List<Element> customFilterElts = DomUtils.getChildElementsByTagName(element, Elements.CUSTOM_FILTER); List<OrderDecorator> customFilters = new ArrayList<OrderDecorator>(); final String ATT_AFTER = "after"; final String ATT_BEFORE = "before"; final String ATT_POSITION = "position"; //循环自定义标签列表custom-filter for (Element elt: customFilterElts) { String after = elt.getAttribute(ATT_AFTER); String before = elt.getAttribute(ATT_BEFORE); String position = elt.getAttribute(ATT_POSITION); String ref = elt.getAttribute(ATT_REF); if (!StringUtils.hasText(ref)) { pc.getReaderContext().error("The '" + ATT_REF + "' attribute must be supplied", pc.extractSource(elt)); } RuntimeBeanReference bean = new RuntimeBeanReference(ref); if(WebConfigUtils.countNonEmpty(new String[] {after, before, position}) != 1) { pc.getReaderContext().error("A single '" + ATT_AFTER + "', '" + ATT_BEFORE + "', or '" + ATT_POSITION + "' attribute must be supplied", pc.extractSource(elt)); } //如果指定了position,直接将filter与order产生关联关系 if (StringUtils.hasText(position)) { customFilters.add(new OrderDecorator(bean, SecurityFilters.valueOf(position))); //如果指定了after,将filter与after值加一产生关联关系 } else if (StringUtils.hasText(after)) { SecurityFilters order = SecurityFilters.valueOf(after); if (order == SecurityFilters.LAST) { customFilters.add(new OrderDecorator(bean, SecurityFilters.LAST)); } else { customFilters.add(new OrderDecorator(bean, order.getOrder() + 1)); } //如果指定了before,将filter与before-1产生关联关系 } else if (StringUtils.hasText(before)) { SecurityFilters order = SecurityFilters.valueOf(before); if (order == SecurityFilters.FIRST) { customFilters.add(new OrderDecorator(bean, SecurityFilters.FIRST)); } else { customFilters.add(new OrderDecorator(bean, order.getOrder() - 1)); } } } return customFilters; }
这里用到三个重要的与排序相关的类及枚举,分别是OrderDecorator、OrderComparator以及SecurityFilters枚举
首先看SecurityFilters枚举定义
enum SecurityFilters { FIRST (Integer.MIN_VALUE), //order=100 CHANNEL_FILTER, //order=200 CONCURRENT_SESSION_FILTER, //依次递增…… SECURITY_CONTEXT_FILTER, LOGOUT_FILTER, X509_FILTER, PRE_AUTH_FILTER, CAS_FILTER, FORM_LOGIN_FILTER, OPENID_FILTER, LOGIN_PAGE_FILTER, DIGEST_AUTH_FILTER, BASIC_AUTH_FILTER, REQUEST_CACHE_FILTER, SERVLET_API_SUPPORT_FILTER, REMEMBER_ME_FILTER, ANONYMOUS_FILTER, SESSION_MANAGEMENT_FILTER, EXCEPTION_TRANSLATION_FILTER, FILTER_SECURITY_INTERCEPTOR, SWITCH_USER_FILTER, LAST (Integer.MAX_VALUE); //这里设置100,主要给自定义过滤器提供after、before的预留位置 //也就是说,在某个默认的过滤器前后只能自定义99个过滤器,虽然可能性几乎为0 private static final int INTERVAL = 100; private final int order; //返回的order值=序号*间隔100 private SecurityFilters() { order = ordinal() * INTERVAL; } private SecurityFilters(int order) { this.order = order; } //主要通过该方法返回Filter的位置 public int getOrder() { return order; } }
由此可见,该类维护了Spring Security中每个filter的顺序
接着看OrderDecorator类。这个类实现org.springframework.core.Ordered接口
class OrderDecorator implements Ordered { BeanMetadataElement bean; int order; //构造函数传递两个参数1.bean定义;2.filter在链中的位置 public OrderDecorator(BeanMetadataElement bean, SecurityFilters filterOrder) { this.bean = bean; this.order = filterOrder.getOrder(); } public OrderDecorator(BeanMetadataElement bean, int order) { this.bean = bean; this.order = order; } //实现接口方法getOrder public int getOrder() { return order; } public String toString() { return bean + ", order = " + order; } }
OrderComparator类的路径是org.springframework.core.OrderComparator,实际上是spring core包的一个比较器,可以顺便看下OrderComparator源码。下面截取的只是部分核心代码
public int compare(Object o1, Object o2) { boolean p1 = (o1 instanceof PriorityOrdered); boolean p2 = (o2 instanceof PriorityOrdered); if (p1 && !p2) { return -1; } else if (p2 && !p1) { return 1; } //前面几行代码主要针对PriorityOrdered,这里不做分析 //分别获取Ordered接口实现类的getOrder方法得到order值 int i1 = getOrder(o1); int i2 = getOrder(o2); //对得到的order进行比较 return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } //获取Ordered接口的实现类,获取getOrder值 protected int getOrder(Object obj) { return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : Ordered.LOWEST_PRECEDENCE); }
通过以上的分析,可以总结如下
1.由SecurityFilters维持位置order
2.由OrderDecorator维持filter与order的对应关系
3.由OrderComparator负责比较OrderDecorator的先后顺序
附上默认的过滤器顺序列表
order | 过滤器名称 |
100 | ChannelProcessingFilter |
200 | ConcurrentSessionFilter |
300 | SecurityContextPersistenceFilter |
400 | LogoutFilter |
500 | X509AuthenticationFilter |
600 | RequestHeaderAuthenticationFilter |
700 | CasAuthenticationFilter |
800 | UsernamePasswordAuthenticationFilter |
900 | OpenIDAuthenticationFilter |
1000 | DefaultLoginPageGeneratingFilter |
1100 | DigestAuthenticationFilter |
1200 | BasicAuthenticationFilter |
1300 | RequestCacheAwareFilter |
1400 | SecurityContextHolderAwareRequestFilter |
1500 | RememberMeAuthenticationFilter |
1600 | AnonymousAuthenticationFilter |
1700 | SessionManagementFilter |
1800 | ExceptionTranslationFilter |
1900 | FilterSecurityInterceptor |
2000 | SwitchUserFilter |
以上标注红色的都已经分析完毕
评论
6 楼
youjianbo_han_87
2013-12-08
Dead_knight 写道
youjianbo_han_87 写道
Dead_knight 写道
leyou 写道
已经找到解决办法了,使用CompositeFilter就行了
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
可以自定义 LogoutFilter不。因为我这边session信息是写到缓存里面的。当登出的时候,需要将缓存里面的权限信息删除。
在logoutfilter前面增加一个自定义过滤器清除缓存的就行了
谢谢,我想到了另外一个思路,应用这边都不需要做特别的配置。
我增加一个监听器,来保存和移除缓存中权限信息,一个过滤器,来恢复当服务器宕机重启或者切换时的权限信息。
5 楼
Dead_knight
2013-12-07
youjianbo_han_87 写道
Dead_knight 写道
leyou 写道
已经找到解决办法了,使用CompositeFilter就行了
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
可以自定义 LogoutFilter不。因为我这边session信息是写到缓存里面的。当登出的时候,需要将缓存里面的权限信息删除。
在logoutfilter前面增加一个自定义过滤器清除缓存的就行了
4 楼
youjianbo_han_87
2013-12-07
Dead_knight 写道
leyou 写道
已经找到解决办法了,使用CompositeFilter就行了
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
可以自定义 LogoutFilter不。因为我这边session信息是写到缓存里面的。当登出的时候,需要将缓存里面的权限信息删除。
3 楼
Dead_knight
2013-11-28
leyou 写道
已经找到解决办法了,使用CompositeFilter就行了
办法很多种啊,可以使用一个after+一个before。或者直接使用position属性直接指定位置
2 楼
leyou
2013-11-28
已经找到解决办法了,使用CompositeFilter就行了
1 楼
leyou
2013-11-28
你好,非常感谢你的文章,看了受益匪浅,不过我想请问一下,关于custom-filter,比如,我需要在LogoutFilter前自定义两个Filter,但是before只能写一个 before="LOGOUT_FILTER",这个该如何解决呢?
发表评论
-
Spring Security3源码分析-电子书下载
2012-07-30 14:34 8625提供电子书下载链接。 -
Spring Security3源码分析-CAS支持
2012-05-13 21:03 25880Spring Security3对CAS的支持主要在这个spr ... -
Spring Security3源码分析-SSL支持
2012-05-10 12:48 11169Sping Security3对于SSL的支持仅仅表现在对需要 ... -
Spring Security3源码分析-认证授权分析
2012-05-09 21:59 6478前面分析了FilterChainProxy执行过程,也对常用的 ... -
Spring Security3源码分析-RequestCacheAwareFilter分析
2012-05-09 12:55 5030RequestCacheAwareFilter过滤器对应的类路 ... -
Spring Security3源码分析-ExceptionTranslationFilter分析
2012-05-09 10:03 7950ExceptionTranslationFilter过滤器对应 ... -
Spring Security3源码分析-SessionManagementFilter分析-下
2012-05-08 21:03 6432很多spring security3资料在 ... -
Spring Security3源码分析-SessionManagementFilter分析-上
2012-05-08 17:26 11036SessionManagementFilter过滤 ... -
Spring Security3源码分析-AnonymousAuthenticationFilter分析
2012-05-08 10:32 5301AnonymousAuthenticationFilter ... -
Spring Security3源码分析-BasicAuthenticationFilter分析
2012-05-08 09:24 9707BasicAuthenticationFilter过滤器对应的 ... -
Spring Security3源码分析-FilterSecurityInterceptor分析
2012-05-07 17:31 15406FilterSecurityInterceptor过滤器对应的 ... -
Spring Security3源码分析-SecurityContextHolderAwareRequestFilter分析
2012-05-07 10:34 6896SecurityContextHolderAwareReque ... -
Spring Security3源码分析-RememberMeAuthenticationFilter分析
2012-05-06 22:33 6043RememberMeAuthenticationFilter过 ... -
Spring Security3源码分析-UsernamePasswordAuthenticationFilter分析
2012-05-06 11:54 24962UsernamePasswordAuthenticationF ... -
Spring Security3源码分析-LogoutFilter分析
2012-05-06 10:18 10473LogoutFilter过滤器对应的类路径为 org.spri ... -
Spring Security3源码分析-SecurityContextPersistenceFilter分析
2012-05-06 08:22 8875通过观察Filter的名字,就能大概猜出来这个过滤器的作用,是 ... -
Spring Security3源码分析-FilterChainProxy执行过程分析
2012-05-06 07:48 4324通过FilterChainProxy的初始化、自定义标签的分析 ... -
Spring Security3源码分析-authentication-manager标签解析
2012-05-05 16:13 21778讲解完http标签的解析过程,authentication-m ... -
Spring Security3源码分析-http标签解析
2012-05-05 15:29 8616在FilterChainProxy初始化的 ... -
Spring Security3源码分析-FilterChainProxy初始化
2012-05-04 16:57 20158很久没有更新博客了,最近对Spring Security做了比 ...
相关推荐
赠送jar包:spring-security-crypto-5.5.2.jar; 赠送原API文档:spring-security-crypto-5.5.2-javadoc.jar; 赠送源代码:spring-security-crypto-5.5.2-sources.jar; 赠送Maven依赖信息文件:spring-security-...
赠送jar包:spring-security-crypto-5.6.1.jar; 赠送原API文档:spring-security-crypto-5.6.1-javadoc.jar; 赠送源代码:spring-security-crypto-5.6.1-sources.jar; 赠送Maven依赖信息文件:spring-security-...
赠送jar包:spring-security-core-5.5.2.jar; 赠送原API文档:spring-security-core-5.5.2-javadoc.jar; 赠送源代码:spring-security-core-5.5.2-sources.jar; 赠送Maven依赖信息文件:spring-security-core-...
赠送jar包:spring-security-core-5.2.0.RELEASE.jar; 赠送原API文档:spring-security-core-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-security-core-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:spring-security-core-5.3.9.RELEASE.jar; 赠送原API文档:spring-security-core-5.3.9.RELEASE-javadoc.jar; 赠送源代码:spring-security-core-5.3.9.RELEASE-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:spring-security-rsa-1.0.10.RELEASE.jar; 赠送原API文档:spring-security-rsa-1.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-security-rsa-1.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:spring-security-oauth2-2.3.5.RELEASE.jar; 赠送原API文档:spring-security-oauth2-2.3.5.RELEASE-javadoc.jar; 赠送源代码:spring-security-oauth2-2.3.5.RELEASE-sources.jar; 赠送Maven依赖信息...
赠送jar包:spring-security-jwt-1.0.10.RELEASE.jar; 赠送原API文档:spring-security-jwt-1.0.10.RELEASE-javadoc.jar; 赠送源代码:spring-security-jwt-1.0.10.RELEASE-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:spring-security-web-5.6.1.jar; 赠送原API文档:spring-security-web-5.6.1-javadoc.jar; 赠送源代码:spring-security-web-5.6.1-sources.jar; 赠送Maven依赖信息文件:spring-security-web-5.6.1....
赠送jar包:spring-security-core-5.0.7.RELEASE.jar; 赠送原API文档:spring-security-core-5.0.7.RELEASE-javadoc.jar; 赠送源代码:spring-security-core-5.0.7.RELEASE-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:spring-security-oauth2-2.3.5.RELEASE.jar; 赠送原API文档:spring-security-oauth2-2.3.5.RELEASE-javadoc.jar; 赠送源代码:spring-security-oauth2-2.3.5.RELEASE-sources.jar; 赠送Maven依赖信息...
spring-boot-security-saml, Spring Security saml与 Spring Boot的集成 spring-boot-security-saml这个项目在处理 spring-security-saml 和 Spring Boot 之间的平滑集成的同时,在处理内部的配置的gritty和锅炉板的...
赠送jar包:spring-security-core-5.6.1.jar; 赠送原API文档:spring-security-core-5.6.1-javadoc.jar; 赠送源代码:spring-security-core-5.6.1-sources.jar; 赠送Maven依赖信息文件:spring-security-core-...
赠送jar包:spring-security-oauth2-autoconfigure-2.1.8.RELEASE.jar; 赠送原API文档:spring-security-oauth2-autoconfigure-2.1.8.RELEASE-javadoc.jar; 赠送源代码:spring-security-oauth2-autoconfigure-...
赠送jar包:spring-security-core-5.6.1.jar; 赠送原API文档:spring-security-core-5.6.1-javadoc.jar; 赠送源代码:spring-security-core-5.6.1-sources.jar; 赠送Maven依赖信息文件:spring-security-core-...
10. **spring-security-config-3.1.2.RELEASE.jar**:提供了基于XML或Java的配置方式,用于定义安全规则和策略,如定义访问控制列表,自定义过滤器链等。 通过以上这些jar包,我们可以深入研究Spring Security Web...
赠送jar包:spring-security-web-5.2.0.RELEASE.jar; 赠送原API文档:spring-security-web-5.2.0.RELEASE-javadoc.jar; 赠送源代码:spring-security-web-5.2.0.RELEASE-sources.jar; 赠送Maven依赖信息文件:...
赠送jar包:spring-security-crypto-5.6.1.jar; 赠送原API文档:spring-security-crypto-5.6.1-javadoc.jar; 赠送源代码:spring-security-crypto-5.6.1-sources.jar; 赠送Maven依赖信息文件:spring-security-...
3. **spring-security-oauth2-2.0.3.RELEASE-sources.jar**:这是源码JAR文件,包含Spring Security OAuth2的原始源代码。对于开发者来说,这是一个宝贵的资源,因为他们可以直接查看和学习库的内部工作原理,调试...
赠送jar包:spring-security-config-5.6.1.jar; 赠送原API文档:spring-security-config-5.6.1-javadoc.jar; 赠送源代码:spring-security-config-5.6.1-sources.jar; 赠送Maven依赖信息文件:spring-security-...