Carregar um segredo do Azure Key Vault em um aplicativo Spring Boot

Este tutorial mostra como usar o Key Vault em aplicativos Spring Boot para proteger dados de configuração confidenciais e recuperar propriedades de configuração do Key Vault. O Key Vault fornece armazenamento seguro de segredos genéricos, como senhas e cadeias de conexão de banco de dados.

Pré-requisitos

Importante

É necessário o Spring Boot versão 2.5 ou posterior para concluir as etapas neste artigo.

Defina um segredo para o Azure Key Vault

Este tutorial descreve como ler credenciais de banco de dados do Key Vault em um aplicativo Spring Boot. Para ler as credenciais do Key Vault, você deve primeiro armazenar as credenciais do banco de dados no Key Vault.

Para armazenar a URL de um banco de dados H2 como um novo segredo no Key Vault, consulte Início Rápido: definir e recuperar um segredo do Azure Key Vault usando o portal do Azure. Neste tutorial, você definirá um segredo com nome h2url e valor jdbc:h2:~/testdb;user=sa;password=password.

Observação

Depois de definir o segredo, conceda ao seu aplicativo acesso ao Key Vault seguindo as instruções em Atribuir uma política de acesso do Key Vault.

Ler um segredo do Azure Key Vault

Agora que as credenciais do banco de dados foram armazenadas no Key Vault, você pode recuperá-las com o Azure Spring Cloud .

Para instalar o módulo iniciador do Azure Key Vault do Azure Spring Cloud, adicione as seguintes dependências ao seu arquivo pom.xml:

  • A lista de materiais (BOM) do Azure Spring Cloud:

    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>com.azure.spring</groupId>
          <artifactId>spring-cloud-azure-dependencies</artifactId>
          <version>5.17.1</version>
          <type>pom</type>
          <scope>import</scope>
        </dependency>
      </dependencies>
    </dependencyManagement>
    

    Observação

    Se você estiver usando o Spring Boot 2.x, certifique-se de definir a spring-cloud-azure-dependencies versão como 4.19.0. Esta lista de materiais (BOM) deve ser configurada na <dependencyManagement> seção do arquivo pom.xml. Isso garante que todas as dependências do Azure Spring Cloud estejam usando a mesma versão. Para obter mais informações sobre a versão usada para esta BOM, consulte Qual versão do Azure Spring Cloud devo usar.

  • O artefato iniciador do Azure Key Vault do Azure Spring Cloud:

    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-keyvault</artifactId>
    </dependency>
    

O Azure Spring Cloud tem vários métodos para ler segredos do Key Vault. Você pode usar os seguintes métodos de forma independente ou combiná-los para diferentes casos de uso:

  • Use o SDK do Azure para o Key Vault.
  • Use o Spring KeyVault PropertySource.

Use o SDK do Azure para o Key Vault

O SDK do Azure para Key Vault fornece SecretClient para gerenciar segredos no Key Vault.

O exemplo de código a seguir mostrará como usar SecretClient para recuperar credenciais de banco de dados H2 do Azure Key Vault.

Para ler um segredo usando o SDK do Azure do Key Vault, configure o aplicativo seguindo estas etapas:

  1. Configure um ponto de extremidade do Key Vault no arquivo de configuração application.properties.

    spring.cloud.azure.keyvault.secret.endpoint=https://<your-keyvault-name>.vault.azure.net/
    
  2. Injete o bean SecretClient em sua aplicação Spring e use o método getSecret para recuperar um segredo, como mostrado no exemplo a seguir:

    import com.azure.security.keyvault.secrets.SecretClient;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class SecretClientApplication implements CommandLineRunner {
    
        // Spring Cloud Azure will automatically inject SecretClient in your ApplicationContext.
        private final SecretClient secretClient;
    
        public SecretClientApplication(SecretClient secretClient) {
            this.secretClient = secretClient;
        }
    
        public static void main(String[] args) {
            SpringApplication.run(SecretClientApplication.class, args);
        }
    
        @Override
        public void run(String... args) {
            System.out.println("h2url: " + secretClient.getSecret("h2url").getValue());
        }
    }
    

    Dica

    Neste tutorial, não há operações de autenticação nas configurações ou no código. No entanto, a conexão com os serviços do Azure requer autenticação. Para concluir a autenticação, você precisa usar a Identidade do Azure. O Azure Spring Cloud usa DefaultAzureCredential, que a biblioteca Azure Identity fornece para ajudá-lo a obter credenciais sem nenhuma alteração de código.

    DefaultAzureCredential dá suporte a vários métodos de autenticação e determina qual método usar no runtime. Essa abordagem habilita seu aplicativo a usar diferentes métodos de autenticação em diferentes ambientes, como ambientes locais e de produção, sem implementar código específico do ambiente. Para obter mais informações, consulte DefaultAzureCredential.

    Para concluir a autenticação em ambientes de desenvolvimento locais, você pode usar a CLI do Azure, o Visual Studio Code, o PowerShell ou outros métodos. Para obter mais informações, consulte Autenticação do Azure em ambientes de desenvolvimento Java. Para concluir a autenticação em ambientes de hospedagem do Azure, recomendamos o uso de identidade gerenciada atribuída pelo usuário. Para obter mais informações, confira O que são as identidades gerenciadas para recursos do Azure?

  3. Inicie o aplicativo. Você verá logs semelhantes ao seguinte exemplo:

    h2url: jdbc:h2:~/testdb;user=sa;password=password
    

Você pode criar o bean SecretClient sozinho, mas o processo é complicado. Em aplicativos Spring Boot, você precisa gerenciar propriedades, aprender o padrão de criação e registrar o cliente no contexto do aplicativo Spring. O exemplo de código a seguir mostra como você cria um bean SecretClient:

import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.security.keyvault.secrets.SecretClient;
import com.azure.security.keyvault.secrets.SecretClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SecretClientConfiguration {

    @Bean
    public SecretClient createSecretClient() {
        return new SecretClientBuilder()
            .vaultUrl("https://<your-key-vault-url>.vault.azure.net/")
            .credential(new DefaultAzureCredentialBuilder().build())
            .buildClient();
    }

}

A lista a seguir mostra alguns dos motivos pelos quais esse código não é flexível ou gracioso:

  • O ponto de extremidade do Key Vault é embutido em código.
  • Se você usa @Value para obter configurações do ambiente Spring, não pode ter dicas de IDE em seu arquivo application.properties.
  • Se você tiver um cenário de microsserviço, o código deverá ser duplicado em cada projeto e é fácil cometer erros e difícil de ser consistente.

Felizmente, não é necessário criar o bean SecretClient sozinho com o Azure Spring Cloud. Em vez disso, você pode injetar SecretClient e usar diretamente as propriedades de configuração com as quais já está familiarizado para configurar o Key Vault. Para obter mais informações, consulte Exemplos de configuração.

O Azure Spring Cloud também fornece as seguintes configurações globais para diferentes cenários. Para obter mais informações, consulte a seção Configuração global para SDKs de serviço do Azure do guia do desenvolvedor do Azure Spring Cloud.

  • Opções de proxy.
  • Opções de nova tentativa.
  • Opções do cliente de transporte HTTP.

Você também pode se conectar a diferentes nuvens do Azure. Para saber mais, consulte Conectar a diferentes nuvens do Azure.

Usar a PropertySource do Spring Key Vault

As seções anteriores mostraram como usar SecretClient no CommandLineRunner para ler o segredo após o início do aplicativo. Em aplicativos Spring Boot, no entanto, a leitura de segredos é necessária antes que o aplicativo seja iniciado. Por exemplo, a propriedade de senha da fonte de dados é necessária antes que o aplicativo seja iniciado. O cenário anterior não funcionará se você deseja armazenar a senha da fonte de dados no Key Vault e ainda usar a configuração automática do Spring para obter uma fonte de dados.

Nesse caso, o Azure Spring Cloud fornece integração de ambiente Spring para carregar segredos do Key Vault antes de criar o contexto do aplicativo. É possível usar o segredo para construir e configurar o bean durante a inicialização do contexto do aplicativo Spring. Essa abordagem é uma maneira transparente de acessar segredos do Key Vault e nenhuma alteração de código é necessária.

O exemplo de código a seguir mostra como usar PropertySource para recuperar credenciais de banco de dados H2 para criar a fonte de dados do Azure Key Vault.

Para recuperar a URL de um banco de dados H2 do Key Vault e armazenar dados do banco de dados H2 usando o Spring Data JPA, configure o aplicativo seguindo estas etapas:

  1. Adicione as seguintes propriedades de ponto de extremidade e fonte de dados do Key Vault ao arquivo de configuração application.properties.

    logging.level.org.hibernate.SQL=DEBUG
    
    spring.cloud.azure.keyvault.secret.property-sources[0].endpoint=https://<your-keyvault-name>.vault.azure.net/
    spring.datasource.url=${h2url}
    
    spring.jpa.hibernate.ddl-auto=create-drop
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    

    Dica

    Para obter exemplos de configuração de propriedade do Azure Spring Cloud, consulte a seção Exemplos de configuração do guia do desenvolvedor do Azure Spring Cloud.

    Dica

    Este exemplo é um cenário de banco de dados simples usando um banco de dados H2. É recomendável usar o Banco de Dados do Azure para MySQL ou o Banco de Dados do Azure para PostgreSQL em um ambiente de produção e armazenar a URL, o nome de usuário e a senha do banco de dados no Azure Key Vault. Se você quiser evitar a senha, as conexões sem senha são uma boa escolha. Para obter mais informações, consulte Conexões sem senha para serviços do Azure.

  2. Crie uma nova classe Java Todo. Essa classe é um modelo de domínio mapeado para a tabela todo, que será criada automaticamente pelo JPA. O código a seguir ignora os métodos getters e setters.

    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.Id;
    
    @Entity
    public class Todo {
    
        public Todo() {
        }
    
        public Todo(String description, String details, boolean done) {
            this.description = description;
            this.details = details;
            this.done = done;
        }
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String description;
    
        private String details;
    
        private boolean done;
    
    }
    
  3. Edite o arquivo de classe de inicialização para mostrar o conteúdo a seguir.

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.context.event.ApplicationReadyEvent;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.annotation.Bean;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    import java.util.stream.Stream;
    
    @SpringBootApplication
    public class KeyvaultApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(KeyvaultApplication.class, args);
        }
    
        @Bean
        ApplicationListener<ApplicationReadyEvent> basicsApplicationListener(TodoRepository repository) {
            return event->repository
                .saveAll(Stream.of("A", "B", "C").map(name->new Todo("configuration", "congratulations, you have set up "
                    + "correctly!", true)).toList())
                .forEach(System.out::println);
        }
    
    }
    
    interface TodoRepository extends JpaRepository<Todo, Long> {
    
    }
    
  4. Inicie o aplicativo. O aplicativo recuperará a URL do banco de dados H2 do Key Vault e, em seguida, se conectará ao banco de dados H2 e armazenará dados no banco de dados. Você verá logs semelhantes ao seguinte exemplo:

    2023-01-13 15:51:35.498 DEBUG 5616 --- [main] org.hibernate.SQL: insert into todo (description, details, done, id) values (?, ?, ?, ?)
    com.contoso.keyvault.Todo@1f
    

Implantar no Azure Spring Apps

Agora que você tem o aplicativo Spring Boot em execução localmente, é hora de movê-lo para produção. Os Aplicativos Spring do Azure facilita a implantação de aplicativos Spring Boot no Azure sem nenhuma alteração no código. O serviço gerencia a infraestrutura dos aplicativos do Spring para que os desenvolvedores possam se concentrar no código. O Azure Spring Apps fornece gerenciamento de ciclo de vida usando monitoramento e diagnóstico abrangentes, gerenciamento de configuração, descoberta de serviços, integração de CI/CD, implantações em “blue-green” e muito mais. Para implantar seu aplicativo nos Aplicativos Spring do Azure, consulte Implantar seu primeiro aplicativo nos Aplicativos Spring do Azure.

Próximas etapas