【问题标题】:Mask json values using logback使用 logback 屏蔽 json 值
【发布时间】:2021-12-05 22:15:29
【问题描述】:

我在我的 spring boot 项目的 logback 配置中使用了下面的 logstash 编码器。

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <pattern>
                <pattern>
                    {
                        "creation_timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss, UTC}",
                        "msg": "%msg",
                        "log_type": "%level",
                     }   
                </pattern>
                <omitEmptyFields>true</omitEmptyFields>
            </pattern>
        </providers>
    </encoder>

我想屏蔽 json 日志消息中的敏感数据。我尝试了以下方法来掩盖键“代码”的值。但它不起作用。

"msg": "%replace(%msg){'\"Code\":'.*'', '\"Code\":'xxx''}",

如何在 logstash appender 中屏蔽 json 值?

【问题讨论】:

    标签: java logging logback logstash-logback-encoder


    【解决方案1】:

    我能够通过编写 ValueMasker 的自定义实现来屏蔽敏感数据

    需要两个组件:

    1. 实现ValueMasker的类
    2. 在您的logback.xml 中声明jsonGeneratorDecorator
    package com.mask;
    
    import com.fasterxml.jackson.core.JsonStreamContext;
    import net.logstash.logback.mask.ValueMasker;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    import java.util.stream.IntStream;
    
    public class SensitiveMaskingPatternLayout implements ValueMasker {
        private Pattern multilinePattern = Pattern.compile("\\\"msg\\\"\\s*:\\s*\\\"(.*?)\\\"", Pattern.MULTILINE);;
        private List<String> maskPatterns = new ArrayList<>();
    
        private String maskMessage(String message) {
    
            StringBuilder sb = new StringBuilder(message);
            Matcher matcher = multilinePattern.matcher(sb);
            while (matcher.find()) {
                IntStream.rangeClosed(1, matcher.groupCount()).forEach(group -> {
                    if (matcher.group(group) != null) {
                        IntStream.range(matcher.start(group), matcher.end(group)).forEach(i -> sb.setCharAt(i, 'x'));
                    }
                });
            }
            return sb.toString();
        }
    
        @Override
        public Object mask(JsonStreamContext context, Object value) {
            if (value instanceof CharSequence) {
                return maskMessage((String) value);
            }
            return value;
        }
    }
    
    
    <configuration>
    
        <appender name="mask" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <pattern>
                        <pattern>
                            {
                                "msg": "%msg",
                                "log_type": "%level"
                            }
                        </pattern>
                        <omitEmptyFields>true</omitEmptyFields>
                    </pattern>
                </providers>
                <logLevel>
                    INFO
                </logLevel>
                <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
                    <valueMasker class="com.mask.SensitiveMaskingPatternLayout"/>
                </jsonGeneratorDecorator>
            </encoder>
        </appender>
    
        <root level="INFO">
            <appender-ref ref="mask" />
        </root>
    
    </configuration>
    

    例子:

    package com.example;
    
    import java.util.HashMap;
    import java.util.Map;
    import org.json.JSONObject;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class App {
    
           private static final Logger logger = LoggerFactory.getLogger(App.class);
    
        public static void main(String[] args) {
            Map<String, String> user = new HashMap<>();
            user.put("user_id", "97588");
            user.put("email_id", "random@email.com");
            user.put("msg", "hello world");
            JSONObject userDetails = new JSONObject(user);
    
            logger.info("MaskingPatternExample log from {}" + userDetails);
        }
    
    }
    
    
    {"msg":"MaskingPatternExample log from {}{\"email_id\":\"random@email.com\",\"msg\":\"xxxxxxxxxxx\",\"user_id\":\"97588\"}","log_type":"INFO"}
    
    

    进一步documentation

    【讨论】:

    • 我需要在 LoggingEventCompositeJsonEncoder 中使用掩码模式。
    • @Maddy - 我更新了答案以反映您的问题。
    • 效果很好。非常感谢。是否可以在 logback.xml 中提到模式而不是在类中?
    • @Maddy - 您可以通过此处列出的 mask 属性来做到这一点 - github.com/logstash/logstash-logback-encoder#masking
    猜你喜欢
    • 2011-06-04
    • 1970-01-01
    • 1970-01-01
    • 2021-12-12
    • 2018-11-07
    • 1970-01-01
    • 2013-04-09
    • 1970-01-01
    • 2013-08-04
    相关资源
    最近更新 更多