«1. Обзор

Хранилище HashiCorp — это инструмент для хранения и защиты секретов. Vault, в целом, решает проблему безопасности при разработке программного обеспечения, связанную с управлением секретами. Чтобы узнать больше об этом, ознакомьтесь с нашей статьей здесь.

Spring Vault предоставляет абстракции Spring для хранилища HashiCorp.

В этом уроке мы рассмотрим пример хранения и извлечения секретов из хранилища.

2. Зависимости Maven

Для начала давайте рассмотрим зависимости, которые нам нужны для начала работы с Spring Vault:

<dependencies>
    <dependency>
        <groupId>org.springframework.vault</groupId>
        <artifactId>spring-vault-core</artifactId>
        <version>2.1.1.RELEASE</version>
    </dependency>
</dependencies>

Последнюю версию spring-vault-core можно найти на Maven Центральный.

3. Настройка Vault

Давайте теперь рассмотрим шаги, необходимые для настройки Vault.

3.1. Создание VaultTemplate

Чтобы защитить наши секреты, нам нужно создать экземпляр VaultTemplate, для которого нам нужны экземпляры VaultEndpoint и TokenAuthentication:

VaultTemplate vaultTemplate = new VaultTemplate(new VaultEndpoint(), 
  new TokenAuthentication("00000000-0000-0000-0000-000000000000"));

3.2. Создание VaultEndpoint

Существует несколько способов создания экземпляра VaultEndpoint. Давайте посмотрим на некоторые из них.

Первый — просто создать его экземпляр с помощью конструктора по умолчанию, который создаст конечную точку по умолчанию, указывающую на http://localhost:8200:

VaultEndpoint endpoint = new VaultEndpoint();

Другой способ — создать VaultEndpoint, указав хост Vault и порт:

VaultEndpoint endpoint = VaultEndpoint.create("host", port);

И, наконец, мы также можем создать его из URL-адреса хранилища:

VaultEndpoint endpoint = VaultEndpoint.from(new URI("vault uri"));

Здесь следует отметить несколько моментов: хранилище будет настроено с корневым токеном 00000000-0000. -0000-0000-000000000000 для запуска этого приложения.

В нашем примере мы использовали TokenAuthentication, но есть и другие поддерживаемые методы аутентификации.

4. Настройка Vault Bean с помощью Spring

С помощью Spring мы можем настроить Vault несколькими способами. Один — путем расширения AbstractVaultConfiguration, а другой — с помощью EnvironmentVaultConfiguration, который использует свойства среды Spring.

Теперь мы рассмотрим оба варианта.

4.1. Использование AbstractVaultConfiguration

Давайте создадим класс, расширяющий AbstractVaultConfiguration, для настройки Spring Vault:

@Configuration
public class VaultConfig extends AbstractVaultConfiguration {

    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("00000000-0000-0000-0000-000000000000");
    }

    @Override
    public VaultEndpoint vaultEndpoint() {
        return VaultEndpoint.create("host", 8020);
    }
}

Этот подход аналогичен тому, что мы видели в предыдущем разделе. Отличие заключается в том, что мы использовали Spring Vault для настройки компонентов Vault, расширив абстрактный класс AbstractVaultConfiguration.

Нам просто нужно предоставить реализацию для настройки VaultEndpoint и ClientAuthentication.

4.2. Использование EnvironmentVaultConfiguration

Мы также можем настроить Spring Vault с помощью EnviromentVaultConfiguration:

@Configuration
@PropertySource(value = { "vault-config.properties" })
@Import(value = EnvironmentVaultConfiguration.class)
public class VaultEnvironmentConfig {
}

EnvironmentVaultConfiguration использует Spring PropertySource для настройки компонентов Vault. Нам просто нужно предоставить файл свойств с некоторыми допустимыми записями.

Более подробную информацию обо всех предопределенных свойствах можно найти в официальной документации.

Для настройки Vault нам потребуется как минимум пара свойств:

vault.uri=https://localhost:8200
vault.token=00000000-0000-0000-0000-000000000000

5. Защита секретов

Мы создадим простой класс Credentials, который сопоставляется с именем пользователя и паролем:

public class Credentials {

    private String username;
    private String password;
    
    // standard constructors, getters, setters
}

~~ ~ Теперь давайте посмотрим, как мы можем защитить наш объект Credentials с помощью VaultTemplate:

Credentials credentials = new Credentials("username", "password");
vaultTemplate.write("secret/myapp", credentials);

Теперь, когда эти строки заполнены, наши секреты сохранены.

Далее мы увидим, как получить к ним доступ.

6. Доступ к секретам

Мы можем получить доступ к защищенным секретам, используя метод read() в VaultTemplate, который возвращает VaultResponseSupport в качестве ответа:

VaultResponseSupport<Credentials> response = vaultTemplate
  .read("secret/myapp", Credentials.class);
String username = response.getData().getUsername();
String password = response.getData().getPassword();

Теперь наши значения секретов готовы.

7. Заключение

В этой статье мы узнали об основах Spring Vault на примере, показывающем, как Vault работает в типичных сценариях.

Как обычно, представленный здесь исходный код можно найти на GitHub.