Sprng Security 架构处理流程
发布日期:2021-06-29 15:52:26 浏览次数:2 分类:技术文章

本文共 4055 字,大约阅读时间需要 13 分钟。

Filter

Spring Security的Servlet支持是基于Servlet的Filter,所以首先看看过滤器的作用是很有帮助的。下图显示了单个HTTP请求的处理程序的典型分层。

在这里插入图片描述

客户端向应用程序发送请求,容器创建一个包含Filter和Servlet的FilterChain,这些filter和Servlet基于请求URI的路径来处理HttpServletRequest

DelegatingFilterProxy

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

在这里插入图片描述

DelegatingFilterProxyApplicationContext查找Bean Filter0,然后调用Bean Filter0DelegatingFilterProxy的伪代码如下所示。

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);}

FilterChainProxy

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

在这里插入图片描述

SecurityFilterChain

SecurityFilterChainFilterChainProxy用来确定应该为这个请求调用哪个Spring Security Filter

在这里插入图片描述

SecurityFilterChain中的Security Filter通常是bean,但是它们注册在FilterChainProxy而不是DelegatingFilterProxy上。FilterChainProxy为直接注册Servlet容器或DelegatingFilterProxy提供了许多优势。

首先,它为所有Spring Security的Servlet支持提供了一个起点。因此,如果您试图排除Spring Security的Servlet支持,那么在FilterChainProxy中添加一个调试点是一个很好的开始。

第二,由于FilterChainProxy是Spring安全使用的中心,它可以执行一些不是可选的任务。例如,它清除SecurityContext以避免内存泄漏。它还应用Spring Security的HttpFirewall来保护应用程序免受某些类型的攻击。

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

事实上,FilterChainProxy可以用来确定应该使用哪个SecurityFilterChain。这允许在应用程序中为不同的片提供完全独立的配置。

在这里插入图片描述

在上图中,FilterChainProxy决定应该使用哪个SecurityFilterChain

  • 只有第一个匹配的SecurityFilterChain将被调用。

  • 如果请求一个/api/messages/的URL,

    • 首先匹配SecurityFilterChain_0/api/**模式,所以只有SecurityFilterChain0将被调用,即使它也匹配SecurityFilterChain_n
  • 如果请求的URL是/messages/

    • 不匹配SecurityFilterChain_0/api/**模式,
    • FilterChainProxy将继续尝试每个SecurityFilterChain
    • 假设没有其他SecurityFilterChain实例匹配SecurityFilterChain_n将被调用。

Security Filters

Security Filter通过SecurityFilterChain API插入到FilterChainProxy中。Filter的顺序很重要。通常不需要知道Spring Security Filter的顺序。然而,有时知道顺序是有益的

下面是Spring Security Filter排序的综合列表:

  • ChannelProcessingFilter
  • ConcurrentSessionFilter
  • WebAsyncManagerIntegrationFilter
  • SecurityContextPersistenceFilter
  • HeaderWriterFilter
  • CorsFilter
  • CsrfFilter
  • LogoutFilter
  • OAuth2AuthorizationRequestRedirectFilter
  • Saml2WebSsoAuthenticationRequestFilter
  • X509AuthenticationFilter
  • AbstractPreAuthenticatedProcessingFilter
  • CasAuthenticationFilter
  • OAuth2LoginAuthenticationFilter
  • Saml2WebSsoAuthenticationFilter
  • ConcurrentSessionFilter
  • OpenIDAuthenticationFilter
  • DefaultLoginPageGeneratingFilter
  • DefaultLogoutPageGeneratingFilter
  • BearerTokenAuthenticationFilter
  • RequestCacheAwareFilter
  • SecurityContextHolderAwareRequestFilter
  • JaasApiIntegrationFilter
  • RememberMeAuthenticationFilter
  • AnonymousAuthenticationFilter
  • OAuth2AuthorizationCodeGrantFilter
  • SessionManagementFilter
  • SwitchUserFilter

处理Security异常

ExceptionTranslationFilter允许将AccessDeniedExceptionAuthenticationException转换为HTTP响应。

ExceptionTranslationFilter作为一个Filter被插入到FilterChainProxy中。

在这里插入图片描述

① 首先,ExceptionTranslationFilter调用FilterChain.doFilter(request, response)来执行应用程序的其余部分。

② 如果用户未经过身份验证或是AuthenticationException,则开始认证

  • 清除SecurityContextHolder
  • HttpServletRequest保存在RequestCache中。当用户认证成功时,将使用RequestCache重新执行原始请求
  • AuthenticationEntryPoint用于从客户端请求凭据。例如,它可能重定向到一个登录页面或发送一个WWW-Authenticate头。

③否则,如果是AccessDeniedException,则拒绝访问。调用AccessDeniedHandler来处理拒绝访问。

ℹ️如果应用程序没有抛出AccessDeniedException或AuthenticationException,那么ExceptionTranslationFilter不会做任何事情。

ExceptionTranslationFilter的伪代码如下所示:

try {
filterChain.doFilter(request, response); } catch (AccessDeniedException | AuthenticationException e) {
if (!authenticated || e instanceof AuthenticationException) {
startAuthentication(); } else {
accessDenied(); }}

转载地址:https://console.blog.csdn.net/article/details/116456486 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring Security框架认证整体梳理
下一篇:Spring Security主要模块

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月09日 19时07分37秒