- 一、架构原理
- 二、Security Filter(Security 功能实现)
- 2.1、认证:UsernamePasswordAuthenticationFilter
- 2.2、授权:FilterSecurityInterceptor
- step1、
FilterSecurityInterceptor
从SecurityContextHolder
获取身份认证信息 - step2、
FilterSecurityInterceptor
根据传递过来的HttpServletRequest
、HttpServletResponse
、FilterChain
构建FilterInvocation
对象 - step3、将
FilterInvocation
传递给SecurityMetadataSource
以获得ConfigAttributes
- step4、将
Authentication
、FilterInvocation
和ConfigAttributes
传递给AccessDecisionManager
- step5、如果拒绝授权,则抛出
AccessDeniedException
。(默认由ExceptionTranslationFilter
处理) - step6、如果访问被授予,
FilterSecurityInterceptor
继续调用FilterChain
剩下的过滤链。
- step1、
当前 Spring Security 版本:5.1.5-RELEASE [Spring Cloud Security 官方文档] [Spring Security 官方文档]
一、架构原理
如图, Spring Security
运行主要由三个类组成:
- DelegatingFilterProxy(Filter)
- FilterChainProxy(Filter)
- SecurityFilterChain(非 Filter 不过持有 FilterChain)
上述三大组件构成了 Spring Security
运行逻辑。
1.1、DelegatingFilterProxy(Filter)
作为入口,在剔除 Spring Security Servlet 支持时可以从该类入手。
中文译名:委托过滤代理。DelegatingFilterProxy
是一个过滤器。DelegatingFilterProxy
作为整个 Spring Security
的处理入口。DelegatingFilterProxy
将整个 spring security
功能集成到 Filter
中。DelegatingFilterProxy
是一个入口,或者说是一个桥接器,本身不做任何认证授权等相关处理。
DelegatingFilterProxy(Filter)
作为中转将 Spring Security
功能集成到了 Servlet 容器中。并将关于 Spring Security 的操作委派给FilterChainProxy
处理
拓展:
DelegatingFilterProxy
持有FilterChainProxy
方式。 借助 Spring ICO 容器,调用getBean(String beanName)
的方式从容器中获取对象。 a、配置类 AbstractSecurityWebApplicationInitializer 定义了bean 名称为:springSecurityFilterChain
。并设置到DelegatingFilterProxy
中。b、
DelegatingFilterProxy
在第一次调用doFilter()
方法时,从 IOC 容器中获取实例对象。
1.2、FilterChainProxy(Filter)
FilterChainProxy
被封装到 DelegatingFilterProxy
中。
Spring Security
servlet 支持相关功能包含在 FilterChainProxy
中。
FilterChainProxy
通过 SecurityFilterChain
将请求交给许多 Filter
实例构建的过滤器链处理。
相关处理逻辑代码如下:
拓展:
FilterChainProxy
在 spring boot 中配置方式。FilterChainProxy
配置位置:WebSecurityConfiguration
(配置类通过@EnableWebSecurity
注解触发).。 配置代码如下:
1.3、SecurityFilterChain(非 Filter)
SecurityFilterChain
对象实例存在于 FilterChainProxy
中,且 FilterChainProxy
持有的是 List<SecurityFilterChain>
。
FilterChainProxy
能够根据 RequestMatcher
匹配 URL 对应的 SecurityFilterChain
。
针对不同 URL 提供了不同的 FilterChainProxy
处理能力。
特殊情况下,同一个 URL 匹配多个 SecurityFilterChain
,但是也只有第一次匹配到的 SecurityFilterChain
会被执行。原因如下:
二、Security Filter(Security 功能实现)
Spring Security
运行主要由三个类组成:
- DelegatingFilterProxy(Filter)
- FilterChainProxy(Filter)
- SecurityFilterChain(非 Filter 不过持有 FilterChain)
具体 Spring Security
功能的实现,由 SecurityFilterChain
中持有的 Filter
过滤器链实现。
Spring Security 默认提供的 Filter
官方文档
- ChannelProcessingFilter
- WebAsyncManagerIntegrationFilter
- SecurityContextPersistenceFilter
- HeaderWriterFilter
- CorsFilter
- CsrfFilter
- LogoutFilter
- OAuth2AuthorizationRequestRedirectFilter
- Saml2WebSsoAuthenticationRequestFilter
- X509AuthenticationFilter
- AbstractPreAuthenticatedProcessingFilter
- CasAuthenticationFilter
- OAuth2LoginAuthenticationFilter
- Saml2WebSsoAuthenticationFilter
[UsernamePasswordAuthenticationFilter](https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#servlet-authentication-usernamepasswordauthenticationfilter)
- OpenIDAuthenticationFilter
- DefaultLoginPageGeneratingFilter
- DefaultLogoutPageGeneratingFilter
- ConcurrentSessionFilter
[DigestAuthenticationFilter](https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#servlet-authentication-digest)
- BearerTokenAuthenticationFilter
[BasicAuthenticationFilter](https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#servlet-authentication-basic)
- RequestCacheAwareFilter
- SecurityContextHolderAwareRequestFilter
- JaasApiIntegrationFilter
- RememberMeAuthenticationFilter
- AnonymousAuthenticationFilter
- OAuth2AuthorizationCodeGrantFilter
- SessionManagementFilter
[ExceptionTranslationFilter](https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#servlet-exceptiontranslationfilter)
[FilterSecurityInterceptor](https://docs.spring.io/spring-security/site/docs/5.5.x/reference/html5/#servlet-authorization-filtersecurityinterceptor)
- SwitchUserFilter
在 Spring Security
中,重点在于 认证 、 授权 。
2.1、认证:UsernamePasswordAuthenticationFilter
实现接口:Filter 等。
2.1.1、抽象父类:AbstractAuthenticationProcessingFilter
AbstractAuthenticationProcessingFilter
定义了 Spring Security
身份认证的基础流程,流程图如下:
step1、构建凭证对象
AbstractAuthenticationProcessingFilter
从HttpServletRequest
中获取用户提交的凭证信息,构建认证对象,具体对象依赖于AbstractAuthenticationProcessingFilter
子类的实现。 如:UsernamePasswordAuthenticationFilter
根据HttpServletRequest
提取的凭证信息构建UsernamePasswordAuthenticationToken
。
step2、凭证对象传递到 Authenticationmanager 进行身份认证
凭证信息传递到
AuthenticationManager
进行身份认证。
step3-1、认证失败处理逻辑
- 借助
SecurityContextHolder
清除认证上下文信息- 如果配置有记住登录功能,调用:RememberMeServices.loginFail
- 调用
AuthenticationFailureHandler
step3-2、身份认证通过
SessionAuthenticationStrategy
接收到新的登录通知SecurityContextHolder
设置上下文信息。之后 SecurityContextPersistenceFilter 将SecurityContext
保存到HttpSession
中。- 如果配置有记住登录功能,调用:
RememberMeServices.loginSuccess
- 发布事件
InteractiveAuthenticationSuccessEvent
.- 调用:AuthenticationSuccessHandler
2.1.2、实现:UsernamePasswordAuthenticationFilter
UsernamePasswordAuthenticationFilter
遵照抽象父类的流程。在次基础上,实现了身份凭证的获取,构建身份凭证对象 ,调用 **AuthenticationManager**
进行身份认证。
相关实现代码如下: