spring-security(十七)Filter顺序及简介

前言:
spring security在web应用中是通过各种各样的filter来做认证和安全控制的,由于filter之间的依赖性,过滤器链中filter的顺序也极其重要,不管实际项目中我们选用了哪些过滤器。
1.filter顺序
[list]
[*]ChannelProcessingFilter,访问协议控制过滤器,可能会将我们重新定向到另外一种协议,如从http转换成https
[*]SecurityContextPersistenceFilter,用来创建一个SecurityContext并存储在SecurityContextHolder中,因为后续filter需要用SecurityContext存储的认证相关信息,所以需要在请求一开始就要把这些信息设置好,这样也能使在认证过程中对SecurityContext的任何修改都可以保存下来,并在请求结束后存储在HttpSession中(以在下次请求时使用)
[*]ConcurrentSessionFilter,并发访问控制过滤器,主要做两件事
[table]
|| 1.从SessionRegistry中获取SessionInformation来判断session是否过期,如果过期,调用配置好的logout handlers,从而使session无效,并调用SessionInformationExpiredStrategy的onExpiredSessionDetected方法实现重定向或者通知用户session已过期
|| 2.如果没有过期,刷新当前session的LastRequest时间,在多用户同时访问时如果配置了最大并发访问数量,会将LastRequest时间最早的session设置成过期,从而实现并发访问控制
[/table]
[*]UsernamePasswordAuthenticationFilter、CasAuthenticationFilter、BasicAuthenticationFilter等认证对应的filter,经过这些过滤器后SecurityContextHolder中将包含一个完全组装好的Authentication对象,从而使后续鉴权能正常执行
[*]SecurityContextHolderAwareRequestFilter,用来将ServletRequest封装成能关联到SecurityContextHolder的SecurityContextHolderAwareRequestWrapper(servlet 2.5版本)或者Servlet3SecurityContextHolderAwareRequestWrapper(servlet3.0+版本),从而提供和servlet的集成功能,如调用HttpServletRequest.getUserPrincipal()、HttpServletRequest.authenticate()、HttpServletRequest.login()、HttpServletRequest.logout()等方法
[*]JaasApiIntegrationFilter,当采用Java Authentication and Authorization Service (JAAS)认证方式时,这个filter用来将SecurityContextHolder中的JaasAuthenticationToken转化成Subject供后续filter使用
[*]RememberMeAuthenticationFilter,记忆认证处理过滤器,如果前面认证对应的filter没有对当前请求进行处理,并且当前的请求的cookie中有启用RememberMe功能的标识时(默认是cookie中有名称是remember-me的参数,对应的值是1,true,OK),这个filter将对请求进行处理, 从cookie中解析出用户,并进行认证处理,之后在SecurityContextHolder中存入一个Authentication对象。
[*]AnonymousAuthenticationFilter,匿名认证处理过滤器,如果前面所有的认证处理没有对请求进行认证处理,这个过滤器会向SecurityContextHolder中存入一个匿名的Authentication对象,赋予ROLE_ANONYMOUS的权限,目的是为了在后面的鉴权操作中能始终获取到一个Authentication进行处理,不用考虑null的情况。
[*]ExceptionTranslationFilter,异常处理过滤器,这个过滤器主要拦截后续过滤器(FilterSecurityInterceptor)操作中抛出的异常,根据异常的类型如AuthenticationException、AccessDeniedException等采取不同的策略,重定向到认证登录页面或重定向到错误页或者直接返回前端一个403码
[*]FilterSecurityInterceptor 安全拦截过滤器类,获取当前请求url对应的ConfigAttribute,并调用accessDecisionManager进行鉴权处理,如果用户有权执行当前请求就调用真实的处理逻辑,否则抛出相应的异常AuthenticationException、AccessDeniedException。
[/list]
2.在spring security中是如何保证filter的顺序呢
2.1 简单来说spring是通过FilterComparator类来保证顺序的
FilterComparator() {
int order = 100;
put(ChannelProcessingFilter.class, order);
order += STEP;
put(ConcurrentSessionFilter.class, order);
order += STEP;
put(WebAsyncManagerIntegrationFilter.class, order);
order += STEP;
put(SecurityContextPersistenceFilter.class, order);
order += STEP;
put(HeaderWriterFilter.class, order);
order += STEP;
put(CorsFilter.class, order);
order += STEP;
put(CsrfFilter.class, order);
order += STEP;
put(LogoutFilter.class, order);
order += STEP;
put(X509AuthenticationFilter.class, order);
order += STEP;
put(AbstractPreAuthenticatedProcessingFilter.class, order);
order += STEP;
filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter",
order);
order += STEP;
put(UsernamePasswordAuthenticationFilter.class, order);
order += STEP;
put(ConcurrentSessionFilter.class, order);
order += STEP;
filterToOrder.put(
"org.springframework.security.openid.OpenIDAuthenticationFilter", order);
order += STEP;
put(DefaultLoginPageGeneratingFilter.class, order);
order += STEP;
put(ConcurrentSessionFilter.class, order);
order += STEP;
put(DigestAuthenticationFilter.class, order);
order += STEP;
put(BasicAuthenticationFilter.class, order);
order += STEP;
put(RequestCacheAwareFilter.class, order);
order += STEP;
put(SecurityContextHolderAwareRequestFilter.class, order);
order += STEP;
put(JaasApiIntegrationFilter.class, order);
order += STEP;
put(RememberMeAuthenticationFilter.class, order);
order += STEP;
put(AnonymousAuthenticationFilter.class, order);
order += STEP;
put(SessionManagementFilter.class, order);
order += STEP;
put(ExceptionTranslationFilter.class, order);
order += STEP;
put(FilterSecurityInterceptor.class, order);
order += STEP;
put(SwitchUserFilter.class, order);
}

在这个类中事先将security中可能会用到的filter顺序定义好,那这个类是如何被调用的呢?
在前面一节([url=http://fengyilin.iteye.com/blog/2411127]spring-security(十六)Filter配置原理[/url]),我们知道spring 安全相关的Filter是在WebSecurity的build方法中调用HttpSecurity的build来将追加到HttpSecurity中filter构建成SecurityFilterChain,再把所有的SecurityFilterChain追加到FilterChainProxy中,最后通过DelegatingFilterProxy注册到ServletContext中的,我们就来看下HttpSecurity的build方法

@Override
protected DefaultSecurityFilterChain performBuild() throws Exception {
Collections.sort(filters, comparator);
return new DefaultSecurityFilterChain(requestMatcher, filters);
}

可以看到,在这个类中构建SecurityFilterChain前会先对filter进行排序,而这个排序类就是FilterComparator,所以不管我们加入到HttpSecurity中的filter顺序是怎样的,spring security最终都会确保我们的Filter是严格按照前面讲述的顺序进行的。具体我们用到的Filter是如何追加到HttpSecurity中的,后续讲具体的Filter时再进行分析。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值