如何在 requestBody 日志中屏蔽用户名和密码

How to mask the userName and password in requestBody logs

下面是我的请求正文 xml,我正在用这个请求进行休息。使用自定义 LoggingInterceptor 来记录请求和响应。我想在日志中屏蔽用户和密码。

<login><credentials user="user" Password="pass"/></login>

     private void traceRequest(final HttpRequest request, final byte[] body) throws IOException {
        logger.trace(
            String.format(
                "REQUEST uri=%s, method=%s, requestBody=%s",
                request.getURI(),
                request.getMethod(),
                new String(body, "UTF-8")));
    }

目前我正在打印如下日志:

LoggingRequestInterceptor - REQUEST uri=http://localhost:8080/, method=POST, requestBody=<login><credentials user="user" Password="pass"/></login>

下面是我的logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">

    <property name="logFile" value="logs/employee.log" />
    <property name="logFile-WS" value="logs/employee-ws.log" />


    <appender name="employee" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logFile}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logFile}.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d [%thread] %-5level %logger{64} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="mainAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logFile-WS}</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${logFile-WS}.%d{yyyy-MM-dd}.gz</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d [%thread] %-5level %logger{64} - %replace(%msg){'having masking logic for other property'}%n</pattern>
        </encoder>
    </appender>
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <logger name="org.springframework.ws.client.MessageTracing" level="TRACE" additivity="false">
        <appender-ref ref="mainAppender" />
    </logger>

    <logger name="org.springframework.ws.server.MessageTracing" level="TRACE" additivity="false">
        <appender-ref ref="mainAppender" />
    </logger>

    <logger name="com.employee.LoggingRequestInterceptor" level="TRACE" additivity="false">
        <appender-ref ref="mainAppender" />
    </logger>


    <root level="${root-log-level:-INFO}">
        <appender-ref ref="stdout"/>
        <appender-ref ref="mainAppender"/>
    </root>
</configuration>

请有人帮我解决这个问题。注意:我正在使用 spring boot 2 和 slf4j logger

参考Mask sensitive data in logs with logback

  1. 在您的项目中添加 logback-spring.xml
  2. 自定义 <patternsProperty> 值中的正则表达式以匹配您要屏蔽的内容。
  3. 从上面的答案中添加 MaskingPatternLayout class(使用更新的,一开始的那个不起作用)

logback-spring.xml


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="Console"
        class="ch.qos.logback.core.ConsoleAppender">
        <encoder
            class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.example.springboot.MaskingPatternLayout">
                <patternsProperty>(?:user|Password)="([a-zA-Z0-9]+)"
                </patternsProperty>
                <pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
            </layout>
        </encoder>
    </appender>

    <!-- LOG everything at INFO level -->
    <root level="info">
        <appender-ref ref="Console" />
    </root>
</configuration>

HelloControllerclass待测试


@RestController
public class HelloController {

    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @RequestMapping("/")
    public String index() {
        logger.info("<login><credentials user=\"user\" Password=\"pass\"/></login>");
        return "Greetings from Spring Boot!";
    }

}

预期输出


2020-04-13 12:38:47,511 [http-nio-8080-exec-1] INFO c.e.springboot.HelloController  - <login><credentials user="****" Password="****"/></login>

更新

  1. 请检查 "console" 是否应为 "stdout"
<root level="${root-log-level:-INFO}">
    <appender-ref ref="console"/>
    <appender-ref ref="mainAppender"/>
</root>  

因为没有找到名称为 "console" 的 appender。

  1. 假设记录器在 LoggingRequestInterceptor 中,您还需要添加 "stdout" appender。
<logger name="com.employee.LoggingRequestInterceptor"
    level="TRACE" additivity="false">
    <appender-ref ref="stdout" />
    <appender-ref ref="mainAppender" />
</logger>

我在 logback.xml 中添加了替换模式。这是屏蔽的用户和密码

<encoder>
            <pattern>%d [%thread] %-5level %logger{64} - %replace(  %replace(  %replace(%msg){'user="[^"]+"', 'user=*****'}  ){'Password="[^"]+"', 'Password=*****'}  ){'my another pattern', 'replacement'}%n</pattern>
</encoder>