Как замаскировать чувствительные поля, такие как пароли, в тесте JSON в Scala?

#json #regex #scala #data-masking

#json #регулярное выражение #scala #маскировка данных

Вопрос:

Так что это похоже на вопрос интервью, но это не так. Прежде чем пометить это как дубликат, пожалуйста, знайте, что я просмотрел другие ответы: 1. решения scala нет, 2. в моем случае нужен способ замаскировать более одного совпадающего ключа.

У меня есть def, который выполняет все мои http-запросы. После отправки запроса я регистрирую запрос и ответ. Поскольку эти запросы имеют тело JSON, которое может иметь или не иметь чувствительное поле, подобное этому:

 challengeAnswer
currPassword
password
answer
oldPassword
  

Я хотел бы создать универсальный сканер JSON, который ГЛУБОКО сканирует ключи данного объекта JSON и маскирует значение, если оно соответствует одному из этих регулярных выражений без учета регистра:

 .*answer.*
.*password.*
  

Пример тела запроса:

 {
    "resetPassQuestion1": "I pity the ...?",
    "resetPassAnswer1": "Foo",
    "resetPassQuestion2": "Let's grab a pint at the ...?",
    "resetPassAnswer2": "Bar",
    "firstname": "John",
    "lastname": "Doe",
    "email": "john.doe@example.com",
    "loginId": "jdoe666",
    "password": "Secret1"
}
  

Мне нужно замаскировать Foo, Bar и Secret1 в этом примере с помощью 5 звездочек, чтобы при печати в журналах они печатались:

 {
    "resetPassQuestion1": "I pity the ...?",
    "resetPassAnswer1": "*****",
    "resetPassQuestion2": "Let's grab a pint at the ...?",
    "resetPassAnswer2": "*****",
    "firstname": "John",
    "lastname": "Doe",
    "email": "john.doe@example.com",
    "loginId": "jdoe666",
    "password": "*****"
}
  

Я не нахожу примеров нечувствительного совпадения регистров. Какой хороший и понятный способ решения этой проблемы с помощью легко читаемого кода.

Комментарии:

1. Являются ли json просто строками или вы используете какую-либо библиотеку?

2. Я использую LiftJson 2.10

3. Можете ли вы также поделиться классами case, если они у вас есть?

Ответ №1:

Итак, я решил это с помощью преобразования LiftJson.

 import net.liftweb.json.JsonParser
import net.liftweb.json.Printer.compact
import net.liftweb.json.JsonAST._

private def maskPasswords(jsonStr: String): String = {
    Try(JsonParser.parse(jsonStr)) match {
        case Success(json) => {
            compact(
                render(
                    json.transform {
                        case JField("password",_) => JString("*****")
                        case JField("oldPassword",_) => JString("*****")
                        case JField("resetPassAnswer2",_) => JString("*****")
                        case JField("resetPassAnswer1",_) => JString("*****")
                    }
                )
            )
        }
        case _ => "**** JsonParsing Failed! **** Masking Everything *****"
    }
}
  

Это не идеально, поскольку каждое новое поле, которое я хочу замаскировать, мне пришлось бы добавлять сюда новую строку, но пока это работает достаточно хорошо для меня.