Caricare un segreto da Azure Key Vault in un'applicazione Spring Boot

Questa esercitazione illustra come usare Key Vault nelle applicazioni Spring Boot per proteggere i dati di configurazione sensibili e recuperare le proprietà di configurazione da Key Vault. Key Vault offre l'archiviazione sicura dei segreti generici, ad esempio password e stringhe di connessione di database.

Prerequisiti

Importante

Spring Boot versione 2.5 o successiva è necessario per completare i passaggi descritti in questo articolo.

Impostare un segreto su Azure Key Vault

Questa esercitazione descrive come leggere le credenziali del database da Key Vault in un'applicazione Spring Boot. Per leggere le credenziali da Key Vault, è prima necessario archiviare le credenziali del database in Key Vault.

Per archiviare l'URL di un database H2 come nuovo segreto in Key Vault, vedere Avvio rapido: Impostare e recuperare un segreto da Azure Key Vault usando il portale di Azure. In questa esercitazione si imposta un segreto con nome h2url e valore jdbc:h2:~/testdb;user=sa;password=password.

Nota

Dopo aver impostato il segreto, concedere all'app l'accesso a Key Vault seguendo le istruzioni riportate in Assegnare un criterio di accesso di Key Vault.

Leggere un segreto da Azure Key Vault

Ora che le credenziali del database sono state archiviate in Key Vault, è possibile recuperarle con Spring Cloud Azure.

Per installare il modulo Spring Cloud Azure Key Vault Starter, aggiungere le dipendenze seguenti al file pom.xml :

  • Spring Cloud Azure Bill of Materials (BOM):

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

    Nota

    Se si usa Spring Boot 2.x, assicurarsi di impostare la spring-cloud-azure-dependencies versione su 4.17.0. Questa distinta base deve essere configurata nella <dependencyManagement> sezione del file di pom.xml . In questo modo tutte le dipendenze di Spring Cloud Azure usano la stessa versione. Per altre informazioni sulla versione usata per questa distinta base, vedere La versione di Spring Cloud azure da usare.

  • Artefatto di Spring Cloud Azure Key Vault Starter:

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

Spring Cloud Azure offre diversi metodi per la lettura dei segreti da Key Vault. È possibile usare i metodi seguenti in modo indipendente o combinarli per casi d'uso diversi:

  • Usare Azure SDK per Key Vault.
  • Usare Spring KeyVault PropertySource.

Usare Azure SDK per Key Vault

Azure SDK per Key Vault fornisce SecretClient la gestione dei segreti in Key Vault.

L'esempio di codice seguente illustra come usare SecretClient per recuperare le credenziali del database H2 da Azure Key Vault.

Per leggere un segreto usando Azure SDK da Key Vault, configurare l'applicazione seguendo questa procedura:

  1. Configurare un endpoint di Key Vault nel file di configurazione application.properties .

    spring.cloud.azure.keyvault.secret.endpoint=https://<your-keyvault-name>.vault.azure.net/
    
  2. Inserire il SecretClient bean nell'applicazione Spring e usare il getSecret metodo per recuperare un segreto, come illustrato nell'esempio seguente:

    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());
        }
    }
    

    Suggerimento

    In questa esercitazione non sono presenti operazioni di autenticazione nelle configurazioni o nel codice. Tuttavia, la connessione ai servizi di Azure richiede l'autenticazione. Per completare l'autenticazione, è necessario usare Identità di Azure. Spring Cloud Azure usa DefaultAzureCredential, che la libreria di identità di Azure fornisce per ottenere le credenziali senza modifiche al codice.

    DefaultAzureCredential supporta più metodi di autenticazione e determina il metodo da usare in fase di esecuzione. Questo approccio consente all'app di usare metodi di autenticazione diversi in ambienti diversi (ad esempio ambienti locali e di produzione) senza implementare codice specifico dell'ambiente. Per altre informazioni, vedere DefaultAzureCredential.

    Per completare l'autenticazione negli ambienti di sviluppo locali, è possibile usare l'interfaccia della riga di comando di Azure, Visual Studio Code, PowerShell o altri metodi. Per altre informazioni, vedere Autenticazione di Azure in ambienti di sviluppo Java. Per completare l'autenticazione negli ambienti di hosting di Azure, è consigliabile usare l'identità gestita assegnata dall'utente. Per altre informazioni, vedere Informazioni sulle identità gestite per le risorse di Azure

  3. Avviare l’applicazione. Verranno visualizzati log simili all'esempio seguente:

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

È possibile creare il SecretClient bean da soli, ma il processo è complicato. Nelle applicazioni Spring Boot è necessario gestire le proprietà, apprendere il modello di generatore e registrare il client nel contesto dell'applicazione Spring. L'esempio di codice seguente illustra come compilare un SecretClient bean:

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();
    }

}

L'elenco seguente illustra alcuni dei motivi per cui questo codice non è flessibile o normale:

  • L'endpoint dell'insieme di credenziali delle chiavi è hardcoded.
  • Se si usano @Value per ottenere configurazioni dall'ambiente Spring, non è possibile avere hint IDE nel file application.properties .
  • Se si ha uno scenario di microservizio, il codice deve essere duplicato in ogni progetto ed è facile commettere errori e rendere difficile la coerenza.

Fortunatamente, la compilazione del SecretClient bean da solo non è necessaria con Spring Cloud Azure. È invece possibile inserire SecretClient e usare direttamente le proprietà di configurazione già note per configurare Key Vault. Per altre informazioni, vedere Esempi di configurazione.

Spring Cloud Azure offre anche le configurazioni globali seguenti per diversi scenari. Per altre informazioni, vedere la sezione Configurazione globale per gli SDK dei servizi di Azure della Guida per sviluppatori di Spring Cloud Azure.

  • Opzioni proxy.
  • Opzioni di ripetizione dei tentativi.
  • Opzioni client di trasporto HTTP.

È anche possibile connettersi a cloud di Azure diversi. Per altre informazioni, vedere Connessione a cloud di Azure diversi.

Usare Spring Key Vault PropertySource

Le sezioni precedenti illustrano come usare SecretClient in CommandLineRunner per leggere il segreto dopo l'avvio dell'applicazione. Nelle applicazioni Spring Boot, tuttavia, la lettura dei segreti è necessaria prima dell'avvio dell'applicazione. Ad esempio, la proprietà password dell'origine dati è necessaria prima dell'avvio dell'applicazione. Lo scenario precedente non funziona se si vuole archiviare la password dell'origine dati in Key Vault e usare comunque la configurazione automatica Spring per ottenere un'origine dati.

In questo caso, Spring Cloud Azure offre l'integrazione dell'ambiente Spring per caricare i segreti da Key Vault prima di compilare il contesto dell'applicazione. È possibile usare il segreto per costruire e configurare il bean durante l'inizializzazione del contesto dell'applicazione Spring. Questo approccio è un modo trasparente per accedere ai segreti da Key Vault e non sono necessarie modifiche al codice.

L'esempio di codice seguente illustra come usare PropertySource per recuperare le credenziali del database H2 per compilare l'origine dati da Azure Key Vault.

Per recuperare l'URL di un database H2 da Key Vault e archiviare i dati dal database H2 usando Spring Data JPA, configurare l'applicazione seguendo questa procedura:

  1. Aggiungere le proprietà dell'endpoint e dell'origine dati dell'insieme di credenziali delle chiavi seguenti al file di configurazione 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
    

    Suggerimento

    Per esempi di configurazione delle proprietà di Spring Cloud Azure, vedere la sezione Esempi di configurazione della Guida per sviluppatori di Spring Cloud Azure.

    Suggerimento

    Questo esempio è uno scenario di database semplice che usa un database H2. È consigliabile usare Database di Azure per MySQL o Database di Azure per PostgreSQL in un ambiente di produzione e archiviare l'URL del database, il nome utente e la password in Azure Key Vault. Se si vuole evitare la password, le connessioni senza password sono una scelta ottimale. Per altre informazioni, vedere Connessioni senza password per i servizi di Azure.

  2. Creare una nuova Todo classe Java. Questa classe è un modello di dominio mappato alla todo tabella che verrà creato automaticamente da JPA. Il codice seguente ignora i getters metodi 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. Modificare il file della classe di avvio per visualizzare il contenuto seguente.

    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. Avviare l’applicazione. L'applicazione recupererà l'URL del database H2 da Key Vault, quindi si connetterà al database H2 e archivierà i dati al database. Verranno visualizzati log simili all'esempio seguente:

    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
    

Distribuire in Azure Spring Apps

Ora che l'applicazione Spring Boot è in esecuzione in locale, è possibile spostarla nell'ambiente di produzione. Azure Spring Apps semplifica la distribuzione di applicazioni Spring Boot in Azure senza modifiche al codice. Il servizio gestisce l'infrastruttura delle applicazioni Spring per consentire agli sviluppatori di concentrarsi sul codice. Azure Spring Apps offre la gestione del ciclo di vita usando monitoraggio e diagnostica completi, gestione della configurazione, individuazione dei servizi, integrazione CI/CD, distribuzioni blu-verde e altro ancora. Per distribuire l'applicazione in Azure Spring Apps, vedere Distribuire la prima applicazione in Azure Spring Apps.

Passaggi successivi