SpringSecurity6从入门到实战之整合原生Filter链
DelegatingFilterProxy
从官网上来进行学习可以看到第一个类就是DelegatingFilterProxy,我们首先看看官网给下的定义.
Spring提供了一个名为DelegatingFilterProxy的过滤器实现,它允许在Servlet容器的生命周期和Spring的ApplicationContext之间架起桥梁。Servlet容器允许使用自己的标准注册过滤器实例,但它不知道Spring定义的Bean。您可以通过标准的Servlet容器机制注册DelegatingFilterProxy,但将所有工作委托给实现过滤器的Spring Bean
通过以上进行官网的翻译,我们知道了DelegatingFilterProxy是Servlet容器与Spring中bean容器的桥梁.我们在Spring框架中的Filter都是通过Bean注入的方式加载在容器中,在这可以得知DelegatingFilterProxy的作用就是实现把Serlet容器中的Filter和Spring容器中的Bean关联起来.所以当客户端请求进来先走过原生Filter之后就会到DelegatingFilterProxy进行关联.详细流程见下图.
下面可以看看相关源码
DelegatingFilterProxy
public class DelegatingFilterProxy extends GenericFilterBean {@Nullableprivate String contextAttribute;@Nullableprivate WebApplicationContext webApplicationContext;@Nullableprivate String targetBeanName;private boolean targetFilterLifecycle = false;@Nullableprivate volatile Filter delegate;private final Object delegateMonitor = new Object();
...}
GenericFilterBean
public abstract class GenericFilterBean implements Filter, BeanNameAware, EnvironmentAware,EnvironmentCapable, ServletContextAware, InitializingBean, DisposableBean {/** Logger available to subclasses. */protected final Log logger = LogFactory.getLog(getClass());@Nullableprivate String beanName;@Nullableprivate Environment environment;@Nullableprivate ServletContext servletContext;@Nullableprivate FilterConfig filterConfig;private final Set<String> requiredProperties = new HashSet<>(4);...}
DelegatingFilterProxy 类继承于抽象类 GenericFilterBean 间接 implements 了 javax.servlet.Filter 接口。SpringSecurity中的Filter是Spring工厂中的Bean,无法直接处理客户端请求,需要通过DelegatingFilterProxy 来进行搭建桥梁.
FiterChainProxy
Spring Security的Servlet支持包含在FilterChainProxy中。FilterChainProxy是Spring Security提供的一种特殊过滤器,允许通过SecurityFilterChain委托给多个Filter实例。因为FilterChainProxy是一个Bean,所以它通常包装在DelegatingFilterProxy中。
- FilterChainProxy 类继承于抽象类 GenericFilterBean 间接 implements 了 javax.servlet.Filter 接口。
- Servlet容器启动时自动调用
- 作用:实现把 请求传递给一或多个 SecurityFilterChain 实例进行认证或授权等(根据客户端的请求去匹配是哪个SecurityFilterChain 中的过滤器),并在需要时重定向或返回错误信息。
- 管理一或多个 SecurityFilterChain 过滤器链,这些过滤器链按顺序进行匹配,直到找到能处理当前请求的过滤器链为止。
SecurityFilterChain 接口
- SecurityFilterChain 和 Servlet 中的 FilterChain 一样,同样维护了很多 Filter,这些 Filter 由 SpringSecurity 提供,每个 Filter 具有不同的职能。
- Spring Security 支持添加1或多个 SecurityFilterChain,每个SecurityFilterChain负责不同的请求(比如依据请求地址进行区分),这样可以为不同的请求设置不同的认证规则。
小结:
- Security Filter 并不是直接放在 Web 项目的原生 FilterChain 中,而是通过一个 FilterChainProxy 来统一管理
- FilterChainProxy 是顶层管理者,统一管理 Security Filter 和 SecurityFIlterChain过滤器链
- 当请求到达 FilterChainProxy 时,会根据当前请求匹配 SecurityFilterChain,然后将请求依次转发给 SecurityFilterChain 中的 Security Filter
- FilterChainProxy 把 SecurityFilterChain 嵌入到 Web项目的原生过滤器链中
- DelegatingFilterProxy 把 FilterChainProxy 整合到原生的过滤器链中
Security Filters
Spring Security 中最终对请求进行处理的就是某个 SecurityFilterChain 中的 Security Filter,这些Filter都设置为 Bean 注入到 Spring容器中,且会按照先后顺序执行。下面展示 Spring Security 中给我们提供的过滤器,以及默认情况下会被加载的过滤器。
过滤器 | 过滤器作用 | 默认是否加载 |
---|---|---|
DisableEncodeUrlFilter | 禁用 URL 重新编码 | YES |
ForceEagerSessionCreationFilter | 管理是否强制生成新session | NO |
ChannelProcessingFilter | 过滤请求协议 HTTP 、HTTPS | NO |
WebAsyncManagerIntegrationFilter | 将 WebAsyncManger 与 SpringSecurity 上下文进行集成 | YES |
SecurityContextHolderFilter | 获取安全上下文 | YES |
SecurityContextPersistenceFilter | 处理请求之前,将安全信息加载到 SecurityContextHolder 中 | NO |
HeaderWriterFilter | 处理头信息加入响应中 | YES |
CorsFilter | 处理跨域问题 | NO |
CsrfFilter | 处理 CSRF 攻击 | YES |
LogoutFilter | 处理注销登录 | YES |
OAuth2AuthorizationRequestRedirectFilter | 处理 OAuth2 认证重定向 | NO |
Saml2WebSsoAuthenticationRequestFilter | 处理 SAML 认证 | NO |
X509AuthenticationFilter | 处理 X509 认证 | NO |
AbstractPreAuthenticatedProcessingFilter | 处理预认证问题 | NO |
CasAuthenticationFilter | 处理 CAS 单点登录 | NO |
OAuth2LoginAuthenticationFilter | 处理 OAuth2 认证 | NO |
Saml2WebSsoAuthenticationFilter | 处理 SAML 认证 | NO |
UsernamePasswordAuthenticationFilter | 处理表单登录 | YES |
OpenIDAuthenticationFilter | 处理 OpenID 认证 | NO |
DefaultLoginPageGeneratingFilter | 配置默认登录页面 | YES |
DefaultLogoutPageGeneratingFilter | 配置默认注销页面 | YES |
ConcurrentSessionFilter | 处理 Session 有效期 | NO |
DigestAuthenticationFilter | 处理 HTTP 摘要认证 | NO |
BearerTokenAuthenticationFilter | 处理 OAuth2 认证的 Access Token | NO |
BasicAuthenticationFilter | 处理 HttpBasic 登录 | YES |
RequestCacheAwareFilter | 处理请求缓存 | YES |
SecurityContextHolderAwareRequestFilter | 包装原始请求 | YES |
JaasApiIntegrationFilter | 处理 JAAS 认证 | NO |
RememberMeAuthenticationFilter | 处理 RememberMe 登录 | NO |
AnonymousAuthenticationFilter | 配置匿名认证 | YES |
OAuth2AuthorizationCodeGrantFilter | 处理OAuth2认证中授权码 | NO |
SessionManagementFilter | 处理 session 并发问题 | NO |
ExceptionTranslationFilter | 处理认证/授权中的异常 | YES |
FilterSecurityInterceptor | 对请求进行权限判断 | NO |
AuthorizationFilter | 对请示进行访问权限处理 | YES |
SwitchUserFilter | 处理账户切换 | NO |
Spring Security 提供了 30 多个过滤器。默认情况下Spring Boot 在对 Spring Security 进行自动化配置时,会创建一个名为 SpringSecurityFilerChain 的过滤器,并注入到 Spring 容器中,这个过滤器将负责所有的安全管理,包括用户认证、授权、重定向到登录页面等.
这里我们通过源码来查看SpringBoot在自动化配置时是不是加载了以上的15个过滤器,SpringSecurityFilerChain是通过SpringSecurity的配置类进行加载的,那么我们进入WebSecurityConfiguration源码:
可以发现这个bean的名称就是springSecurityFilerChain,我们打上断点看看默认进行加载的过滤器有哪些
最终可以发现确实加载了这15个过滤器进来