参考文章 https://springdoc.cn/spring-security/servlet/architecture.html
1、什么是spring security
Spring Security是一个Java框架,用于保护应用程序的安全性。它提供了一套全面的安全解决方案,包括身份验证、授权、防止攻击等功能。Spring Security基于过滤器链的概念,可以轻松地集成到任何基于Spring的应用程序中。它支持多种身份验证选项和授权策略,开发人员可以根据需要选择适合的方式。此外,Spring Security还提供了一些附加功能,如集成第三方身份验证提供商和单点登录,以及会话管理和密码编码等。
Spring Security是一个强大且易于使用的框架,可以帮助开发人员提高应用程序的安全性和可靠性。而我们最常用的两个功能就是认证和鉴权,因此作为入门文章本文也只介绍这两个功能的使用
2、架构
上图是Spring Security官方提供的架构图。我们先看图的左边部分,就是一个典型Servlet
Filter
(过滤器)处理流程,我们依次讲解流程涉及的组件
本节讨论了 Spring Security 在基于 Servlet 的应用程序中的高级架构。我们在参考资料中的 认证(Authentication)、授权(Authorization) 和 防止漏洞 部分建立了这种高层次的理解
Filter(过滤器)回顾

客户端向应用程序发送一个请求,容器创建一个 FilterChain
,其中包含 Filter
实例和 Servlet
,应该根据请求URI的路径来处理 HttpServletRequest
。在Spring MVC应用程序中,Servlet是 DispatcherServlet
的一个实例。一个 Servlet
最多可以处理一个 HttpServletRequest
和 HttpServletResponse
。然而,可以使用多个 Filter
来完成如下工作。
- 防止下游的
Filter
实例或 Servlet
被调用。在这种情况下,Filter
通常会使用 HttpServletResponse
对客户端写入响应。
- 修改下游的
Filter
实例和 Servlet
所使用的 HttpServletRequest
或 HttpServletResponse
。
过滤器的力量来自于传入它的 FilterChain
。
由于一个 Filter
只影响下游的 Filter
实例和 Servlet
,所以每个 Filter
的调用顺序是非常重要的。
DelegatingFilterProxy
Spring 提供了一个名为 DelegatingFilterProxy
的 Filter
实现,允许在 Servlet 容器的生命周期和 Spring 的 ApplicationContext
之间建立桥梁。Servlet容器允许通过使用自己的标准来注册 Filter
实例,但它不知道 Spring 定义的 Bean。你可以通过标准的Servlet容器机制来注册 DelegatingFilterProxy
,但将所有工作委托给实现 Filter
的Spring Bean。
下面是 DelegatingFilterProxy
如何融入 Filter
实例和 FilterChain
的图片。

DelegatingFilterProxy
从 ApplicationContext
查找 Bean Filter0,然后调用 Bean Filter0。下面的列表显示了 DelegatingFilterProxy
的伪代码。
DelegatingFilterProxy
Pseudo Code
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { Filter delegate = getFilterBean(someBeanName); delegate.doFilter(request, response); }
延迟地获取被注册为Spring Bean的 Filter。 对于 DelegatingFilterProxy 中的例子,delegate 是 Bean Filter0 的一个实例。 |
|
DelegatingFilterProxy
的另一个好处是,它允许延迟查找 Filter
Bean实例。这一点很重要,因为在容器启动之前,容器需要注册 Filter
实例。然而, Spring 通常使用 ContextLoaderListener
来加载 Spring Bean,这在需要注册 Filter
实例之后才会完成。
FilterChainProxy
Spring Security 的 Servlet 支持包含在 FilterChainProxy
中。FilterChainProxy
是 Spring Security 提供的一个特殊的 Filter
,允许通过 SecurityFilterChain
委托给许多 Filter
实例。由于 FilterChainProxy
是一个Bean,它通常被包裹在 DelegatingFilterProxy 中。

SecurityFilterChain
SecurityFilterChain
被 FilterChainProxy 用来确定当前请求应该调用哪些 Spring Security Filter
实例。
下图显示了 SecurityFilterChain
的作用。

SecurityFilterChain
中的 Security Filter 通常是Bean,但它们是用 FilterChainProxy
而不是 DelegatingFilterProxy 注册的。与直接向Servlet容器或 DelegatingFilterProxy 注册相比,FilterChainProxy
有很多优势。首先,它为 Spring Security 的所有 Servlet 支持提供了一个起点。由于这个原因,如果你试图对 Spring Security 的 Servlet 支持进行故障诊断,在 FilterChainProxy
中添加一个调试点是一个很好的开始。
其次,由于 FilterChainProxy
是 Spring Security 使用的核心,它可以执行一些不被视为可有可无的任务。 例如,它清除了 SecurityContext
以避免内存泄漏。它还应用Spring Security的 HttpFirewall
来保护应用程序免受某些类型的攻击。
此外,它在确定何时应该调用 SecurityFilterChain
方面提供了更大的灵活性。在Servlet容器中,Filter
实例仅基于URL被调用。 然而,FilterChainProxy
可以通过使用 RequestMatcher
接口,根据 HttpServletRequest
中的任何内容确定调用。

Security Filter
Security Filter 是通过 SecurityFilterChain API 插入 FilterChainProxy 中的。
这些 filter 可以用于许多不同的目的,如 认证、 授权、 漏洞保护 等等。filter 是按照特定的顺序执行的,以保证它们在正确的时间被调用,例如,执行认证的 Filter
应该在执行授权的 Filter
之前被调用。一般来说,没有必要知道 Spring Security 的 Filter
的顺序。但是,有些时候知道顺序是有好处的,如果你想知道它们,可以查看 FilterOrderRegistration
代码。
为了解释上面这段话,让我们考虑以下 security 配置:
@Configuration @EnableWebSecurity public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http .csrf(Customizer.withDefaults())
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated() )
.httpBasic(Customizer.withDefaults())
.formLogin(Customizer.withDefaults());
return http.build(); } }