You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring中OpenFeign调试日志屏蔽密码的有效方案求助

Spring中OpenFeign调试日志屏蔽密码的有效方案求助

各位好,我在Spring项目里用了一套很基础的OpenFeign配置来调用第三方REST API,功能上一切正常,但遇到了一个头疼的问题:调试日志里会明文打印出请求体中的密码,而我又必须保持全局DEBUG日志级别开启,不能因为这个就降低整体日志等级。

先给大家看一下我的现有配置:

1. Feign客户端配置类

@EnableConfigurationProperties
public class FeignClientConfiguration {

    @Bean
    @ConfigurationProperties("myapp.gateways.xapi.auth.parameters")
    public Map<String, String> authParameters() {
        return new HashMap<>();
    }

    @Bean
    public RequestInterceptor authInterceptor(final AuthGateway authGateway, 
                                              final @Qualifier("authParameters") Map<String, String> authParameters) {
        return new AuthInterceptor(authGateway, authParameters);
    }
}

2. 配置文件(application.yml)

myapp:
  gateways:
    xapi:
      auth:
        token-uri: ${TOKEN_URI}
        parameters:
          username: ${AUTH_USERNAME}
          password: ${AUTH_PASSWORD}
      api:
        base-uri: ${BASE_URI}

3. Feign客户端接口

@FeignClient(
    name = "ApiGateway",
    url = "${myapp.gateways.xapi.api.base-uri}",
    configuration = FeignClientConfiguration.class
)
public interface ApiGateway {

    @PostMapping("/some/path")
    Result something(@RequestBody MyBody myBody);
}

问题现象

我的日志级别设置为DEBUG,在输出里能直接看到明文密码:

DEBUG [http-nio-8085-exec-2] org.springframework.cloud.openfeign.support.SpringEncoder - Writing [{password=2uSxxxx9by, username=apiuser@xapi}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@70ed03e4] d4bdf27f-bb64-4535-9d57-f4697acbb3a2

已经尝试过但无效的方案

我搜了不少方案试了,但都没解决问题,给大家列一下:

方案1:修改Feign日志级别为BASIC

@Bean
public feign.Logger.Level feignLoggerLevel() {
    return feign.Logger.Level.BASIC;
}

无效原因:这条泄露密码的日志是SpringEncoder打印的,不是OpenFeign自带Logger的输出,所以修改Feign日志级别根本管不到这里。

方案2:自定义MaskingFeignLogger做日志脱敏

@Bean
public feign.Logger feignLogger() {
    return new MaskingFeignLogger();
}

public class MaskingFeignLogger extends feign.Logger {
    @Override
    protected void log(String configKey, String format, Object... args) {
        String message = String.format(format, args);
        // 掩码处理密码字段
        message = message.replaceAll("\"password\"\\s*:\\s*\".*?\"", "\"password\":\"*****\"");
        LoggerFactory.getLogger(configKey).debug(message);
    }
}

无效原因:这个自定义Logger只处理OpenFeign自身的日志输出,而密码是被SpringEncoder提前打印出来的,等这个Logger生效的时候密码已经泄露了。

方案3:自定义RequestInterceptor修改请求体

@Bean
public RequestInterceptor sensitiveDataInterceptor() {
    return new SensitiveDataInterceptor();
}

public class SensitiveDataInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        String body = template.requestBody().asString();
        if (body != null) {
            String sanitized = body.replaceAll("\"password\"\\s*:\\s*\".*?\"", "\"password\":\"*****\"");
            template.body(sanitized);
        }
    }
}

无效原因:拦截器修改的是实际发送给第三方的请求体,但SpringEncoder在序列化请求体的时候,还是会把原始的带明文密码的对象打印到日志里,所以还是能看到密码。

我的核心需求

  • 必须保持全局DEBUG日志级别开启,不能因为这个问题就降低其他模块的日志等级
  • 只需要屏蔽日志中出现的明文密码,其他调试日志正常输出

有没有大佬遇到过类似的问题?求一个真正有效的解决办法,万分感谢!

火山引擎 最新活动