在 Spring Security 过滤器链之前记录请求标头

Posted

技术标签:

【中文标题】在 Spring Security 过滤器链之前记录请求标头【英文标题】:Logging a request header before Spring Security filter chain 【发布时间】:2020-12-27 03:53:56 【问题描述】:

我想尽早记录给定的传入请求标头的内容。

我知道CommonsRequestLoggingFilter 或日志记录HandlerInterceptor 之类的方法,但是这些方法似乎只在 Spring 执行了许多其他代码(例如 Spring Security 过滤器链)后才会记录。

我想在之前记录,Spring 尽可能早地基于一个要求:日志消息需要能够从 HTTP 请求中提取标头。 p>

有没有办法做到这一点?

【问题讨论】:

您尽早需要日志的原因是什么?这会在网关/负载平衡器级别更有效地记录吗? 调试 Spring Security 过滤器中出现的问题。当您拥有大量日志时,就不可能将它们关联起来。如果我们可以尽早将关联令牌放入 MDC,那么所有这些日志将很容易与给定请求关联。 【参考方案1】:

我找到了一种使用嵌入式 Tomcat 的方法。由于它在 Spring 之前接收到请求,因此您可以从这里捕获整个已调度的请求。

public class CustomLoggerValve extends ValveBase 
    private static final Logger logger = LoggerFactory.getLogger(CustomLoggerValve.class);

    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException 
        try 
            MDC.put("requestId", UUID.randomUUID().toString());
            logger.info("Received request");
            getNext().invoke(request, response);
         finally 
            MDC.remove("requestId");
        
    

由于我使用没有 Spring Boot 的 Spring,我可以直接将其添加到我的 Tomcat:

Tomcat tomcat = // ... your tomcat setup
tomcat.getService().getContainer().getPipeline().addValve(new CustomLoggerValve());

我没试过,不过it looks like you could add this quite easily in Spring Boot也是。

类似的方法可能适用于嵌入式 Jetty/其他 JVM Web 服务器。

【讨论】:

以上是关于在 Spring Security 过滤器链之前记录请求标头的主要内容,如果未能解决你的问题,请参考以下文章

spring security 提供的CsrfFilter过滤器

在 Spring Security 过滤器链之前记录请求标头

spring security 11种过滤器介绍

在 Spring Cloud Gateway 的 Spring Security 过滤器链中插入自定义过滤器

如何在 Spring Security 中编写自定义过滤器?

如何避免自定义过滤器在spring-security中为不安全的url运行