Spring Security 系列第0章

2023-4-29|2023-5-20
麦兜
麦兜
type
Post
status
Published
date
Apr 29, 2023
slug
summary
tags
安全
Spring
category
技术分享
password
icon

介绍

Spring Security 是一个安全框架,它提供身份验证授权和针对常见攻击的保护。它支持 Servlet Reactive 应用的保护。
 
以上是 Spring 官方的介绍,从开发人员角度来说它就是一串大的 Filter (FilterChain 责任链设计模式),一个接着一个。对于早期 Java Web 开发人员最熟悉不过了。

回顾 Filter

notion image
大多数流行的 Java Web 还是运行在 Tomcat 容器之上,所以还是说 Tomcat 容器为主,Tomcat 是 Servlet 容器规范的一种实现。Servlet 规范中有很多组件,比如 Servlet 组件,Filter 组件等,不同组件有不同功能。(千万别把规范和组件搞混)
为了屏蔽 Filter 组件细节,Servlet 规范也提出接口让用户实现,也就是在 Java Web 应用中实现过滤器的 Filter 接口
 
Filter 是用于修改 HTTP 请求和响应的一条流水线,客户端向服务端发送请求时候先由 Tomcat 转发到 Filter,多个 Filter 在 Tomcat 会创建为 FilterChain 形成一条链。
 
只要能满足当前的 Filter 就可以通过调用 doFilter 传递给下一个 Filter,否则就直接返回,走不到受保护的业务代码。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { // do something before the rest of the application chain.doFilter(request, response); // invoke the rest of the application // do something after the rest of the application }

整体架构

通过上述知道 Filter 可以做到检测请求或修改响应,Spring Security 就是实现 Filter 完成的。
 
notion image
 
在 Spring Security 的 Filter 实现类为 DelegatingFilterProxy 它作为 Servlet 容器和 Spring 的桥梁,也就是定义在 Spring Bean 的 Filter 也能注册到 Servlet 容器,它另一个好处是它允许延迟加载 Filter 实例。
这是 DelegatingFilterProxy 的伪代码。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { // Lazily get Filter that was registered as a Spring Bean // For the example in DelegatingFilterProxy delegate is an instance of Bean Filter0 Filter delegate = getFilterBean(someBeanName); // delegate work to the Spring Bean delegate.doFilter(request, response); }
 
DelegatingFilterProxy 里面包含一个 FilterChainPorxy 是一个特殊的 Filter Bean ,它被 Spring 管理。它主要用于根据 HttpServletRequest 内容匹配调用其他 Security FilterSecurity Filter 是扩展更多功能的 Filter。
 
Security Filters 框架内置实现,不同的 Filter 实现的是身份验证授权和针对常见攻击的保护功能。
  • CasAuthenticationFilter
  • OAuth2LoginAuthenticationFilter
  • Saml2WebSsoAuthenticationFilter
  • UsernamePasswordAuthenticationFilter

Q&A

Q:为什么不用 DelegatingFilterProxy 直接匹配 URL,而是用 FilterChainPoryx?
A: 因为需要清理 SecurityContext 带来的内存。
 
Q:为什么 Spring Security 有这么多内置过滤器?
A:这些过滤器的实现都是来自业界内定义好的协议实现,就比如 HTTP 协议一样。
 
 
Spring Security 系列第1章[译] 去掉云计算和k8s —— 把应用迁移回本地