SpringSecurity(2):过滤器链(filterchain)的介绍
spring framework上⼀节中,主要讲了Spring Security认证和授权的核⼼组件及核⼼⽅法。但是,什么时候调⽤这些⽅法呢?答案就是Filter和AOP。Spring Security在我们进⾏⽤户认证以及授予权限的时候,通过各种各样的来控制权限的访问。
对于基于HttpRequest的⽅式对端点进⾏保护,我们使⽤⼀个Filter Chain来保护;对于基于⽅法调⽤进⾏保护,我们使⽤AOP来保护。本篇重点讲Spring Security中过滤器链的种类及过滤器中如何实现的认证和授权。
Spring Security会默认为我们添加15个过滤器,我们可以从WebSecurity(WebSecurity是Spring Security加载的⼀个重要对象,将在下节具体讲述)的performBuild()⽅法中看到过滤器链SecurityFilterChain的构建过程,并交由FilterChainProxy对象代理。我们从SecurityFilterChain的默认实现类DefaultSecurityFilterChain中的log看出,Spring Security由以下过滤器组成了过滤器链:
Creating filter chain: any request, [
org.springframework.t.request.async.WebAsyncManagerIntegrationFilter@7f353a0f,
org.springframework.t.SecurityContextPersistenceFilter@4735d6e5,
org.springframework.security.web.header.HeaderWriterFilter@314a31b0,
org.springframework.security.web.csrf.CsrfFilter@4ef2ab73,
org.springframework.security.web.authentication.logout.LogoutFilter@57efc6fd,
org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@d88f893,
org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@2cd388f5,
org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@7ea2412c,
org.springframework.security.web.authentication.www.BasicAuthenticationFilter@2091833,
org.springframework.security.web.savedrequest.RequestCacheAwareFilter@4dad0eed,
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@16132f21,
org.springframework.security.web.authentication.AnonymousAuthenticationFilter@1c93b51e,
org.springframework.security.web.session.SessionManagementFilter@59edb4f5,
org.springframework.security.web.access.ExceptionTranslationFilter@104dc1a2,
org.springframework.security.web.access.intercept.FilterSecurityInterceptor@1de0641b
]
下⾯就是各个过滤器的功能,其中SecurityContextPersistenceFilter,UsernamePasswordAuthenticationFilter及FilterSecurityInterceptor分别对应了上节SecurityContext,AuthenticationManager,AccessDecisionManager的处理。
[WebAsyncManagerIntegrationFilter](异步⽅式)提供了对securityContext和WebAsyncManager的集成。⽅式是通过SecurityContextCallableProcessingInterceptor的beforeConcurrentHandling(NativeWebRequest, Callable)⽅法来将SecurityContext设置到Callable上。其实就是把SecurityContext设置到异步线程中,使其也能获取到⽤户上下⽂认证信息。
[SecurityContextPersistenceFilter] (同步⽅式)在请求之前从SecurityContextRepository(默认实现是HttpSessionSecurityContextRepository)获取信息并填充SecurityContextHolder(如果没有,则创建⼀个新的ThreadLocal的SecurityContext),并在请求完成并清空SecurityContextHolder并更新SecurityContextRepository。
在Spring Security中,虽然安全上下⽂信息被存储于Session中,但实际的Filter中不应直接操作Session(过滤器⼀般负责核⼼的处理流程,⽽具体的业务实现,通常交给其中聚合的其他实体类),⽽是⽤如HttpSessionSecurityContextRepository中
loadContext(),saveContext()来存取session。
[HeaderWriterFilter]⽤来给http响应添加⼀些Header,⽐如X-Frame-Options,X-XSS-Protection*,X-Content-Type-Options。
[CsrfFilter]默认开启,⽤于防⽌csrf攻击的过滤器
[LogoutFilter]处理注销的过滤器
[UsernamePasswordAuthenticationFilter]表单提交了username和password,被封装成UsernamePasswordAuthenticationToken对象进⾏⼀系列的认证,便是主要通过这个过滤器完成的,即调⽤AuthenticationManager.authenticate()。在表单认证的⽅法中,这是最最关键的过滤器。具体过程是:
(1)调⽤AbstractAuthenticationProcessingFilter.doFilter()⽅法执⾏过滤器
(2)调⽤UsernamePasswordAuthenticationFilter.attemptAuthentication()⽅法
(3)调⽤AuthenticationManager.authenticate()⽅法(实际上委托给AuthenticationProvider的实现类来处理)[DefaultLoginPageGeneratingFilter] & [DefaultLogoutPageGeneratingFilter]如果没有配置/login及login page, 系统则会⾃动配置这两个Filter。[BasicAuthenticationFilter] Processes a HTTP request's BASIC authorization headers, putting the result into the SecurityContextHolder.
[RequestCacheAwareFilter]内部维护了⼀个RequestCache,⽤于缓存request请求
[SecurityContextHolderAwareRequestFilter]此过滤器对ServletRequest进⾏了⼀次包装,使得request具有更加丰富的API(populates the ServletRequest with a request wrapper which implements servlet API security methods)
[AnonymousAuthenticationFilter]匿名⾝份过滤器,spring security为了兼容未登录的访问,也⾛了⼀套认证流程,只不过是⼀个匿名的⾝份。它位于⾝份认证过滤器(e.g. UsernamePasswordAuthenticationFilter)之后,意味着只有在上述⾝份过滤器执⾏完毕后,SecurityContext依旧没有⽤户信
息,AnonymousAuthenticationFilter该过滤器才会有意义。
[SessionManagementFilter]和session相关的过滤器,内部维护了⼀个SessionAuthenticationStrategy来
执⾏任何与session相关的活动,⽐如session-fixation protection mechanisms or checking for multiple concurrent logins。
[ExceptionTranslationFilter]异常转换过滤器,这个过滤器本⾝不处理异常,⽽是将认证过程中出现的异常(AccessDeniedException and AuthenticationException)交给内部维护的⼀些类去处理。它
位于整个springSecurityFilterChain的后⽅,⽤来转换整个链路中出现的异常,将其转化,顾名思义,转化以意味本⾝并不处理。⼀般其只处理两⼤类异常:AccessDeniedException访问异常和AuthenticationException认证异常。
它将Java中的异常和HTTP的响应连接在了⼀起,这样在处理异常时,我们不⽤考虑密码错误该跳到什么页⾯,账号锁定该如何,只需要关注⾃⼰的业务逻辑,抛出相应的异常便可。如果该过滤器检测到AuthenticationException,则将会交给内部的AuthenticationEntryPoint去处理,如果检测到AccessDeniedException,需要先判断当前⽤户是不是匿名⽤户,如果是匿名访问,则和前⾯⼀样运⾏AuthenticationEntryPoint,否则会委托给AccessDeniedHandler去处理,⽽AccessDeniedHandler的默认实现,是AccessDeniedHandlerImpl。
[FilterSecurityInterceptor] 这个过滤器决定了访问特定路径应该具备的权限,这些受限的资源访需要什么权限或⾓⾊,这些判断和处理都是由该类进⾏的。(1)调⽤FilterSecurityInterceptor.invoke()⽅法执⾏
过滤器
(2)调⽤AbstractSecurityInterceptor.beforeInvocation()⽅法
(3)调⽤AccessDecisionManager.decide()⽅法决策判断是否有该权限
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论