Spring Security工作原理(一)

发布时间:2024年01月19日

过滤器

Spring Security的Servlet支持是基于Servlet过滤器的,因此首先了解过滤器的一般作用是很有帮助的。下图显示了单个HTTP请求处理程序的典型分层结构。

在这里插入图片描述
处理客户端发送的请求时,容器创建一个FilterChain,其中包含Filter实例和Servlet,根据请求URI的路径处理HttpServletRequest。在Spring MVC应用程序中,Servlet是DispatcherServlet的一个实例。最多一个Servlet可以处理单个HttpServletRequest和HttpServletResponse。然而,可以使用多个过滤器来:

  • 防止调用下游的Filter实例或Servlet。在这种情况下,Filter通常会编写HttpServletResponse。
  • 修改下游Filter实例和Servlet使用的HttpServletRequest或HttpServletResponse。

Filter 的功能,在于FilterChain 里面的filter。

FilterChain 使用案例

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
}

由于过滤器仅影响下游过滤器实例和Servlet,因此调用每个过滤器的顺序非常重要。

DelegatingFilterProxy

Spring提供了一个名为DelegatingFilterProxy的Filter实现,它允许在Servlet容器的生命周期和Spring的ApplicationContext之间进行桥接。Servlet容器允许使用其自己的标准注册Filter实例,但它不知道Spring定义的Bean。您可以通过标准的Servlet容器机制注册DelegatingFilterProxy,但将所有工作委托给实现Filter的Spring Bean。

这是DelegatingFilterProxy如何适配到Filter实例和FilterChain的图片。
在这里插入图片描述

DelegatingFilterProxy会从ApplicationContext中查找名为Filter0的Bean,然后调用Filter0 Bean。以下是DelegatingFilterProxy的伪代码示例:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
	Filter delegate = getFilterBean(someBeanName);
	delegate.doFilter(request, response);
}
  1. DelegatingFilterProxy延迟获取作为Spring Bean注册的Filter。在DelegatingFilterProxy示例中,delegate是Bean Filter0的一个实例。
  2. 将工作委托给Spring Bean。

DelegatingFilterProxy的另一个好处是它允许延迟查找Filter bean实例。这很重要,因为容器在启动之前需要注册Filter实例。然而,Spring通常使用ContextLoaderListener来加载Spring Beans,这个过程直到Filter实例需要被注册之后才会完成。

FilterChainProxy

Spring Security的Servlet支持包含在FilterChainProxy中。FilterChainProxy是Spring Security提供的特殊Filter,它通过SecurityFilterChain允许委派给许多Filter实例。由于FilterChainProxy是一个Bean,通常会被包装在DelegatingFilterProxy中。

在这里插入图片描述

SecurityFilterChain

SecurityFilterChain被FilterChainProxy用来确定当前请求应该调用哪些Spring Security过滤器实例。

以下图片展示了SecurityFilterChain的作用。

在这里插入图片描述

SecurityFilterChain中的安全过滤器通常是Bean,但它们是注册到FilterChainProxy而不是DelegatingFilterProxy。FilterChainProxy相比直接注册到Servlet容器或DelegatingFilterProxy,提供了许多优势。首先,它为Spring Security的所有Servlet支持提供了一个起点。因此,如果您尝试解决Spring Security的Servlet支持问题,在FilterChainProxy中设置一个调试点是一个很好的起点。

第二,由于FilterChainProxy在Spring Security的使用中是至关重要的,它可以执行一些被视为非可选的任务。例如,它清除SecurityContext以避免内存泄漏。它还应用了Spring Security的HttpFirewall来保护应用程序免受某些类型的攻击。

此外,它在确定何时应调用SecurityFilterChain时提供了更多的灵活性。在Servlet容器中,过滤器实例仅根据URL调用。然而,FilterChainProxy可以通过使用RequestMatcher接口根据HttpServletRequest中的任何内容来确定调用。

以下图片显示了多个SecurityFilterChain实例。
在这里插入图片描述

在多个SecurityFilterChain图中,FilterChainProxy决定使用哪个SecurityFilterChain。只有第一个匹配的SecurityFilterChain会被调用。如果请求的URL是/api/messages/,它首先匹配SecurityFilterChain-0的模式/api/,所以只有SecurityFilterChain0被调用,即使它也匹配SecurityFilterChain-n。如果请求的URL是/messages/,它不匹配SecurityFilterChain-0的模式/api/,所以FilterChainProxy会继续尝试每个SecurityFilterChain。假设没有其他SecurityFilterChain实例匹配,那么SecurityFilterChain-n会被调用。

请注意,SecurityFilterChain-0只配置了三个安全过滤器实例。然而,SecurityFilterChain-n配置了四个安全过滤器实例。重要的是要注意,每个SecurityFilterChain都可以是独特的,并且可以独立配置。实际上,如果应用程序希望Spring Security忽略某些请求,SecurityFilterChain可能不包含任何安全过滤器实例。

文章来源:https://blog.csdn.net/uniquewonderq/article/details/135656202
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。