1. Обзор
В этом руководстве мы покажем, как мы можем использовать хранилище Hashicorp в приложениях Spring Boot для защиты конфиденциальных данных конфигурации.
Мы предполагаем, что у нас есть некоторое знание Vault и что у нас уже есть тестовая установка . Если это не так, давайте на минутку прочитаем наш учебник Vault Intro , чтобы мы могли познакомиться с его основами.
2. Весеннее облачное хранилище
Spring Cloud Vault является относительно недавним дополнением к стеку Spring Cloud, которое позволяет приложениям получать доступ к секретам, хранящимся в экземпляре Vault, прозрачным способом .
В целом переход на Vault — очень простой процесс: просто добавьте необходимые библиотеки и добавьте несколько дополнительных свойств конфигурации в наш проект, и все готово. Никаких изменений кода не требуется!
Это возможно, потому что он действует как PropertySource
с высоким приоритетом, зарегистрированный в текущей среде
.
Таким образом, Spring будет использовать его всякий раз, когда требуется свойство. Примеры включают свойства DataSource ,
ConfigurationProperties
и т. д.
3. Добавление Spring Cloud Vault в проект Spring Boot
Чтобы включить библиотеку spring-cloud-vault
в проект Spring Boot на основе Maven, мы используем связанный начальный
артефакт, который вытянет все необходимые зависимости.
Помимо основного стартера,
мы также включим spring-vault-config-databases
, который добавляет поддержку динамических учетных данных базы данных:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config-databases</artifactId>
</dependency>
Последнюю версию стартового Spring Cloud Vault можно загрузить с Maven Central.
3.1. Базовая конфигурация
Для правильной работы Spring Cloud Vault нужен способ определить, где связаться с сервером Vault и как аутентифицироваться на нем.
Мы делаем это, предоставляя необходимую информацию в application.yml
или application.properties
:
spring:
cloud:
vault:
uri: https://localhost:8200
ssl:
trust-store: classpath:/vault.jks
trust-store-password: changeit
config:
import: vault://
Свойство spring.cloud.vault.uri
указывает на адрес API Vault. Поскольку наша тестовая среда использует HTTPS с самозаверяющим сертификатом, нам также необходимо предоставить хранилище ключей, содержащее его открытый ключ.
Обратите внимание, что эта конфигурация не имеет данных аутентификации . В простейшем случае, когда мы используем фиксированный токен, мы можем передать его через системное свойство spring.cloud.vault.token
или переменную среды. Этот подход хорошо работает в сочетании со стандартными механизмами облачной конфигурации, такими как ConfigMaps или секреты Docker Kubernetes.
Spring Vault также требует дополнительной настройки для каждого типа секрета, который мы хотим использовать в нашем приложении. В следующих разделах описывается, как мы можем добавить поддержку двух распространенных типов секретов: ключ/значение и учетные данные базы данных.
4. Использование бэкэнда Generic Secrets
Мы используем бэкэнд Generic Secret для доступа к неверсионным
секретам, хранящимся в виде пар ключ-значение в Vault .
Предполагая, что у нас уже есть зависимость spring-cloud-starter-vault-config
в нашем пути к классам
, все, что нам нужно сделать, это добавить несколько свойств в файл application.yml :
spring:
cloud:
vault:
# other vault properties omitted ...
generic:
enabled: true
application-name: fakebank
В этом случае свойство application-name
является необязательным. Если не указано, Spring вместо этого примет значение стандартного spring.application.name
.
Теперь мы можем использовать все пары ключ/значение, хранящиеся в secret/fakebank
, как любое другое свойство среды
.
Следующий фрагмент показывает, как мы можем прочитать значение ключа foo
, хранящегося по этому пути:
@Autowired Environment env;
public String getFoo() {
return env.getProperty("foo");
}
Как мы видим, сам код ничего не знает о Vault, и это хорошо! Мы по-прежнему можем использовать фиксированные свойства в локальных тестах и переключаться на Vault по своему усмотрению, просто включив одно свойство в приложении .yml
.
4.1. Примечание о профилях Spring
Если доступно в текущей среде,
Spring Cloud Vault будет использовать доступные имена профилей в качестве суффикса, добавленного к указанному базовому пути, по которому будет выполняться поиск пар ключ/значение .
Он также будет искать свойства в настраиваемом пути к приложению по умолчанию (с суффиксом профиля и без него), чтобы мы могли иметь общие секреты в одном месте. Используйте эту функцию с осторожностью!
Подводя итог, можно сказать, что если рабочий профиль нашего приложения fakebank
активен
, Spring Vault будет искать свойства, хранящиеся по следующим путям: ``
секрет/
фейкбанк/производство
(более высокий приоритет)секретный /
поддельный банксекрет/применение/производство
секрет/приложение
(более низкий приоритет)
В предыдущем списке приложение
— это имя, которое Spring использует в качестве дополнительного местоположения по умолчанию для секретов. Мы можем изменить его, используя свойство spring.cloud.vault.generic.default-context
.
Свойства, хранящиеся по наиболее конкретному пути, будут иметь приоритет над остальными. Например, если одно и то же свойство foo
доступно по указанным выше путям, порядок приоритета будет следующим:
5. Использование базы данных Secret Backend
Базовый модуль базы данных позволяет приложениям Spring использовать динамически генерируемые учетные данные базы данных, созданные Vault . Spring Vault внедряет эти учетные данные в стандартные свойства spring.datasource.username
и spring.datasource.password
, чтобы их можно было выбрать с помощью обычных DataSource
s.
Обратите внимание, что перед использованием этого бэкенда мы должны создать конфигурацию базы данных и роли в Vault, как описано в нашем предыдущем руководстве .
Чтобы использовать учетные данные базы данных, сгенерированные Vault, в нашем приложении Spring, базы данных spring-cloud-vault-config-database
должны присутствовать в пути к классам проекта вместе с соответствующим драйвером JDBC.
Нам также нужно включить его использование в нашем приложении, добавив несколько свойств в наш application.yml:
spring:
cloud:
vault:
# ... other properties omitted
database:
enabled: true
role: fakebank-accounts-rw
Наиболее важным свойством здесь является свойство роли
, которое содержит имя роли базы данных, хранящееся в Vault. Во время запуска Spring свяжется с Vault и запросит создание новых учетных данных с соответствующими привилегиями.
Хранилище по умолчанию аннулирует привилегии, связанные с этими учетными данными, по истечении настроенного срока жизни.
К счастью, Spring Vault автоматически продлит аренду, связанную с полученными учетными данными. При этом учетные данные будут оставаться действительными, пока работает наше приложение.
Теперь давайте посмотрим на эту интеграцию в действии. Следующий фрагмент получает новое подключение к базе данных из источника данных, управляемого Spring
:
Connection c = datasource.getConnection();
И снова мы видим, что в нашем коде нет никаких признаков использования Vault . Вся интеграция происходит на уровне среды
, поэтому наш код можно легко протестировать, как обычно.
6. Заключение
В этом руководстве мы показали, как интегрировать Vault с Spring Boot с помощью библиотеки Spring Vault. Мы рассмотрели два распространенных случая использования: общие пары ключ/значение и учетные данные динамической базы данных.
Пример проекта, содержащий все необходимые зависимости, тесты интеграции и сценарии установки хранилища, доступен на GitHub .