[spring-projects/spring-boot]为 Spring Security 过滤器链提供执行器端点

2024-04-23 169 views
0

如果能有一份为 Web Servlet 堆栈和 Web Reactive 堆栈定义的 Spring Security 过滤器链的报告,那就太好了。

生成的 JSON 示例(仅包括 Servlet 堆栈)

得到/actuator/filterchains

{
  "filterChains": {
    "servlets": [
      {
        "requestMatcher": "Ant [pattern='/web1/**']",
        "filterDetails": [
          {
            "className": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter"
          },
          {
            "className": "org.springframework.security.web.context.SecurityContextPersistenceFilter"
          },
          {
            "className": "org.springframework.security.web.header.HeaderWriterFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.logout.LogoutFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter"
          },
          {
            "className": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter"
          },
          {
            "className": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter"
          },
          {
            "className": "org.springframework.security.web.session.SessionManagementFilter"
          },
          {
            "className": "org.springframework.security.web.access.ExceptionTranslationFilter"
          }
        ]
      },
      {
        "requestMatcher": "OrRequestMatcher [requestMatchers=[Ant [pattern='/web2/**'], Ant [pattern='/web3/**']]]",
        "filterDetails": [
          {
            "className": "org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter"
          },
          {
            "className": "org.springframework.security.web.context.SecurityContextPersistenceFilter"
          },
          {
            "className": "org.springframework.security.web.header.HeaderWriterFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.logout.LogoutFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter"
          },
          {
            "className": "org.springframework.security.web.savedrequest.RequestCacheAwareFilter"
          },
          {
            "className": "org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"
          },
          {
            "className": "org.springframework.security.web.authentication.AnonymousAuthenticationFilter"
          },
          {
            "className": "org.springframework.security.web.session.SessionManagementFilter"
          },
          {
            "className": "org.springframework.security.web.access.ExceptionTranslationFilter"
          }
        ]
      }
    ],
    "reactive": []
  }
}

回答

1

谢谢你的建议。您能否描述一下如何使用端点公开的信息?

执行器的主要目的是提供应用程序在生产环境中运行时有用的信息。我想知道上面的信息在开发时是否更有用。因此,它可能属于 Boot 的 DevTools 或 Spring Security 中的不同形式。

/抄送@rwinch

3

@威尔金索纳

感谢您的答复。

谢谢你的建议。您能否描述一下如何使用端点公开的信息?

我将以与执行器返回的dispatcherServlet和字段提供的信息类似的方式使用该信息。我认为这些信息是免费的,因此它提供了 Spring Boot 应用程序配置的更完整的概述。servletFiltersmappings

执行器的主要目的是提供应用程序在生产环境中运行时有用的信息。我想知道上面的信息在开发时是否更有用。因此,它可能属于 Boot 的 DevTools 或 Spring Security 中的不同形式。

我知道这些信息是敏感的,并且可能只在开发过程中有用,但我认为对于执行器提供的数据也可以这样说mappings

我经常DebugFilter在 Spring Security 中启用 来查看所有过滤器链(和过滤器)是如何设置以及如何评估它们的。当我在 JavaConfig 中进行具有许多过滤器链和不同安全过滤器的复杂配置时,我发现这特别有用。使用此方法将信息记录在 Spring Boot 的默认日志输出中。必须搜索/ grep 日志总是有点痛苦,这就是我为其编写执行器的原因。

如果您觉得这些信息并不真正属于执行器,那么 Spring Security 已经提供了记录过滤器链和过滤器的功能,因此最好解决这个问题。

0

@rwinch 请问您对此有何看法?

0

我们肯定需要对 Spring Security 匹配器进行一些更改,以便它们有一个好的toString()

9

@wilkinsona我不知道如何在 Boot 不需要深入了解内部结构的情况下执行此操作。按照目前的情况,您可以从FilterChainProxy.getFilterChains()获取映射。但是,SecurityFilterChainAPI 不公开底层,RequestMatcherDefaultSecurityFilterChain实现确实允许访问RequestMatcher.我不确定我会推荐依赖具体的实现。

@philwebb 许多RequestMatchers 都有一个定义的toString().如果您发现一些需要改进的地方,请随时创建问题或 PR。

1

谢谢,@rwinch。你认为自己有多内向DefaultSecurityFilterChain?如果其公共 API 稳定,我们可以防御性地依赖它,并在SecurityFilterChain使用不同的实现时使端点不为匹配器返回任何内容。

如果我们这样做,事情就不会与我们为不同处理程序类型公开不同信息的映射端点有太大不同。但是,在映射情况下,我们可以按类型对映射进行分组,从而使响应的每个部分的结构可预测。对于安全过滤器链,我认为我们无法做到这一点,因为它们的顺序很重要,因此我们希望将它们全部放在一起,而不管具体类型如何。

还有一个问题是toString()顶级匹配器上的 a 实际上有多大用处。输出不太可能特别适合解析。如果我们不小心,我们就有可能重现 1.5 中映射端点遇到的问题并在 2.0 中修复。

7

WebFilterChainProxy@rwinch @wilkinsona Spring Security 中的 Web 反应式堆栈也没有使用 getFilterChains() 方法。

2

@威尔金索纳

您认为 DefaultSecurityFilterChain 的内部性如何?

我可能应该用不同的措辞。它不被视为内部的,而只是特定于实现的。该 API 相当稳定,但您可能会遇到不同的实现。

0

好点,@marcelvdh。这是 Spring Security 中两个 API 的一个有趣的区别。上也没有匹配器的访问器MatcherSecurityWebFilterChain

我暂时将此标记为已阻止,因为如果我们决定在这里做某事,我们希望能够对两个 Web 堆栈执行此操作,这将需要 Spring Security 中的 API 更改。

@rwinch 由于我们并没有完全相信这一变化的价值,我认为这个问题不应该推动 Spring Security 中的 API 变化。但是,如果您认为所需的更改本身具有优点,那么我们当然可以考虑在此基础上进行构建。

0

我们暂时关闭这个。如果 Spring Security 进行必要的更改,我们可以重新访问。

7

@philwebb 您能否在 Spring Security 中创建或指向有关必要更改的票证?如果这些更改能够推动所需的功能,我愿意进行一些更改。

8

@rwinch 正如我上面所说,我们认为这个问题不应该推动 Spring Security 的任何变化:

由于我们并没有完全相信这一变化的价值,我认为这个问题不应推动 Spring Security 中的 API 变化。但是,如果您认为所需的更改本身具有优点,那么我们当然可以考虑在此基础上进行构建。

如果这些变化有机地发生,那么我们会考虑在它们的基础上进行构建,但我认为 Boot 不应该向它们提出请求。

1

@wilkinsona我想我觉得这是一个用户的自然请求,想要一个 Boot 无法实现的功能,除非 Spring Security 进行更改。我非常有兴趣了解 Boot 认为有必要进行哪些更改。

6

如果 @marcelvdh 热衷于看到这一功能,也许他们可以打开一个?即使我们在启动中不做任何事情,对安全性的一些更改也将允许他们实现自己的端点。

5

我对目前的情况很满意。正如 @wilkinsona 提到的,他认为提议的更​​改并没有为 Spring Boot 作为执行器增加太多价值,并且其原因对我来说很有意义。

@rwinch我很乐意为WebFilterChainProxy.javagetFilterChains()上缺少的Spring Security 创建票证。在 Web 反应式堆栈上。此方法确实存在于Web Servlet 堆栈中的FilterChainProxy.java中。