Activer HTTPS dans Spring Boot avec des certificats Azure Key Vault

Ce tutoriel vous montre comment sécuriser vos applications Spring Boot (y compris Azure Spring Apps) avec des certificats TLS/SSL à l’aide d’Azure Key Vault et d’identités managées pour les ressources Azure.

Les applications Spring Boot de démarrage Spring en production, qu’elles soient dans le cloud ou locales, nécessitent un chiffrement de bout en bout pour le trafic réseau utilisant des protocoles TLS standard. La plupart des certificats TLS/SSL que vous rencontrez sont découvrables à partir d’une autorité de certification racine publique. Toutefois, cette découverte n’est parfois pas possible. Quand les certificats ne sont pas découvrables, l’application doit disposer d’un moyen de charger ces certificats, de les présenter aux connexions réseau entrantes et de les accepter à partir de connexions réseau sortantes.

Les applications Spring Boot activent généralement le protocole TLS en installant les certificats. Les certificats sont installés dans le magasin de clés local de la machine virtuelle Java qui exécute l’application Spring Boot. Avec Spring sur Azure, les certificats ne sont pas installés localement. Au lieu de cela, l’intégration de Spring pour Microsoft Azure offre un moyen sécurisé et fluide d’activer TLS à l’aide d’Azure Key Vault et de l’identité managée pour les ressources Azure.

Diagram showing interaction of elements in this tutorial.

Important

Actuellement, Spring Cloud Azure Certificate starter version 4.x ou ultérieure ne prend pas en charge TLS/mTLS, ils configurent uniquement automatiquement le client de certificat Key Vault. Par conséquent, si vous souhaitez utiliser TLS/mTLS, vous ne pouvez pas migrer vers la version 4.x.

Prérequis

  • Un abonnement Azure - En créer un gratuitement

  • Kit de développement Java (JDK) pris en charge avec version 11.

  • Apache Maven version 3.0 ou ultérieure.

  • Azure CLI.

  • cURL ou un utilitaire HTTP similaire pour tester la fonctionnalité.

  • Instance de machine virtuelle Azure. Si vous n’en avez pas, utilisez la commande az vm create et l’image Ubuntu fournie par UbuntuServer pour créer une instance de machine virtuelle avec une identité managée affectée par le système activée. Accordez le Contributor rôle à l’identité managée affectée par le système, puis définissez l’accès scope à votre abonnement.

  • Une instance Azure Key Vault. Si vous n’en avez pas, consultez démarrage rapide : Créer un coffre de clés à l’aide du Portail Azure.

  • Une application Spring Boot. Si vous n’en avez pas, créez un projet Maven avec Spring Initializr. Veillez à sélectionner Maven Project et, sous Dépendances, ajoutez la dépendance Spring Web , puis sélectionnez Java version 8 ou ultérieure.

Important

Spring Boot version 2.5 ou ultérieure est nécessaire pour effectuer les étapes décrites dans cet article.

Définir un certificat TLS/SSL auto-signé

Les étapes décrites de ce tutoriel s’appliquent à n’importe quel certificat TLS/SSL (dont ceux auto-signés) stocké directement dans Azure Key Vault. Les certificats auto-signés ne sont pas adaptés pour être utilisés en production, mais ils sont utiles pour les applications de développement et de test.

Ce tutoriel utilise un certificat auto-signé. Pour définir le certificat, consultez Démarrage rapide : Définir et récupérer un certificat à partir d’Azure Key Vault à l’aide du Portail Azure.

Remarque

Après avoir défini le certificat, accordez à la machine virtuelle l’accès à Key Vault en suivant les instructions fournies dans Affecter une stratégie d’accès Key Vault.

Connexion sécurisée via un certificat TLS/SSL

Vous disposez maintenant d’une machine virtuelle et d’une instance Key Vault et vous avez accordé l’accès à la machine virtuelle à Key Vault. Les sections suivantes montrent comment se connecter en toute sécurité via des certificats TLS/SSL à partir d’Azure Key Vault dans l’application Spring Boot. Ce tutoriel présente les deux scénarios suivants :

  • Exécuter une application Spring Boot avec des connexions entrantes sécurisées
  • Exécuter une application Spring Boot avec des connexions sortantes sécurisées

Conseil

Dans les étapes suivantes, le code sera empaqueté dans un fichier exécutable et chargé sur la machine virtuelle. N’oubliez pas d’installer OpenJDK sur la machine virtuelle.

Exécuter une application Spring Boot avec des connexions entrantes sécurisées

Lorsque le certificat TLS/SSL pour la connexion entrante provient d’Azure Key Vault, configurez l’application en procédant comme suit :

  1. Ajoutez les dépendances suivantes à votre fichier pom.xml :

    <dependency>
       <groupId>com.azure.spring</groupId>
       <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId>
       <version>3.14.0</version>
    </dependency>
    
  2. Configurez les informations d’identification Key Vault dans le fichier de configuration application.properties .

    server.ssl.key-alias=<the name of the certificate in Azure Key Vault to use>
    server.ssl.key-store-type=AzureKeyVault
    server.ssl.trust-store-type=AzureKeyVault
    server.port=8443
    azure.keyvault.uri=<the URI of the Azure Key Vault to use>
    

    Ces valeurs permettent à l’application Spring Boot d’exécuter l’action charger pour le certificat TLS/SSL, comme indiqué au début du tutoriel. Le tableau suivant décrit les valeurs des propriétés.

    Propriété Description
    server.ssl.key-alias Valeur de l’argument --name que vous avez passé à az keyvault certificate create.
    server.ssl.key-store-type Doit être AzureKeyVault.
    server.ssl.trust-store-type Doit être AzureKeyVault.
    server.port Port TCP local sur lequel écouter les connexions HTTPS.
    azure.keyvault.uri Propriété vaultUri retournée dans la sortie JSON de la commande az keyvault create. Vous avez enregistré cette valeur dans une variable d’environnement.

    La seule propriété spécifique à Key Vault est azure.keyvault.uri. L’application est en cours d’exécution sur une machine virtuelle dont l’identité managée affectée par le système s’est vu accorder l’accès au coffre de clés. Par conséquent, l’accès est également accordé à l’application.

    Ces changements permettent à l’application Spring Boot de charger le certificat TLS/SSL. À l’étape suivante, vous allez autoriser l’application à effectuer l’action d’acceptation pour le certificat TLS/SSL, comme mentionné au début du didacticiel.

  3. Modifiez le fichier de classe de démarrage afin qu’il dispose du contenu suivant.

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @SpringBootApplication
    @RestController
    public class SsltestApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SsltestApplication.class, args);
        }
    
        @GetMapping(value = "/ssl-test")
        public String inbound(){
            return "Inbound TLS is working!!";
        }
    
        @GetMapping(value = "/exit")
        public void exit() {
            System.exit(0);
        }
    
    }
    

    L’appel de System.exit(0) à partir d’un appel GET REST non authentifié sert uniquement à des fins de démonstration. N’utilisez pas System.exit(0) dans une vraie application.

    Ce code illustre l’action présenter mentionnée au début de ce tutoriel. La liste suivante met en évidence certains détails de ce code :

    • Il y a maintenant une annotation @RestController sur la classe SsltestApplication générée par Spring Initializr.
    • Il existe une méthode annotée avec @GetMapping, avec un value pour l’appel HTTP que vous effectuez.
    • La méthode inbound retourne simplement un message d’accueil quand un navigateur envoie une requête HTTPS au chemin /ssl-test. La méthode inbound illustre la façon dont le serveur présente le certificat TLS/SSL au navigateur.
    • La exit méthode entraîne la sortie de la machine virtuelle JVM lorsqu’elle est appelée. Cette méthode est pratique pour faciliter l’exécution de l’exemple dans le cadre de ce tutoriel.
  4. Exécutez les commandes suivantes pour compiler le code et le empaqueter dans un fichier JAR exécutable.

    mvn clean package
    
  5. Vérifiez que le groupe de sécurité réseau créé dans <your-resource-group-name> autorise le trafic entrant sur les ports 22 et 8443 à partir de votre adresse IP. Pour en savoir plus sur la configuration des règles de groupe de sécurité réseau pour autoriser le trafic entrant, consultez la section Utiliser des règles de sécurité de la rubrique Créer, changer ou supprimer un groupe de sécurité réseau.

  6. Placez le fichier JAR exécutable sur la machine virtuelle.

    cd target
    sftp azureuser@<your VM public IP address>
    put *.jar
    

    Maintenant que vous avez créé l’application Spring Boot et l’avez chargée sur la machine virtuelle, procédez comme suit pour l’exécuter sur la machine virtuelle et appeler le point de terminaison REST avec curl.

  7. Utilisez SSH pour vous connecter à la machine virtuelle, puis exécutez le fichier JAR exécutable.

    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  8. Ouvrez un nouvel interpréteur de commandes Bash, puis exécutez la commande suivante pour vérifier que le serveur présente le certificat TLS/SSL.

    curl --insecure https://<your VM public IP address>:8443/ssl-test
    
  9. Appelez le chemin exit pour arrêter le serveur et fermer les sockets réseau.

    curl --insecure https://<your VM public IP address>:8443/exit
    

Maintenant que vous avez vu la charge et présenter des actions avec un certificat TLS/SSL auto-signé, apportez des modifications triviales à l’application pour voir également l’action d’acceptation.

Exécuter une application Spring Boot avec des connexions sortantes sécurisées

Dans cette section, vous modifiez le code de la section précédente afin que le certificat TLS/SSL pour les connexions sortantes provient d’Azure Key Vault. Par conséquent, les actions charger, présenter et accepter sont satisfaites à partir du coffre de clés Azure.

  1. Ajoutez la dépendance du client Apache HTTP à votre fichier pom.xml :

    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
       <version>4.5.13</version>
    </dependency>
    
  2. Ajoutez un nouveau point de terminaison REST appelé ssl-test-outbound. Ce point de terminaison ouvre un socket TLS sur lui-même et vérifie que la connexion TLS accepte le certificat TLS/SSL. Remplacez la partie précédente de la classe de démarrage par le code suivant.

    import java.security.KeyStore;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import com.azure.security.keyvault.jca.KeyVaultLoadStoreParameter;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.ssl.SSLContexts;
    
    @SpringBootApplication
    @RestController
    public class SsltestApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SsltestApplication.class, args);
        }
    
        @GetMapping(value = "/ssl-test")
        public String inbound(){
            return "Inbound TLS is working!!";
        }
    
        @GetMapping(value = "/ssl-test-outbound")
        public String outbound() throws Exception {
            KeyStore azureKeyVaultKeyStore = KeyStore.getInstance("AzureKeyVault");
            KeyVaultLoadStoreParameter parameter = new KeyVaultLoadStoreParameter(
                System.getProperty("azure.keyvault.uri"));
            azureKeyVaultKeyStore.load(parameter);
            SSLContext sslContext = SSLContexts.custom()
                                               .loadTrustMaterial(azureKeyVaultKeyStore, null)
                                               .build();
    
            HostnameVerifier allowAll = (String hostName, SSLSession session) -> true;
            SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, allowAll);
    
            CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .build();
    
            HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();
    
            requestFactory.setHttpClient(httpClient);
            RestTemplate restTemplate = new RestTemplate(requestFactory);
            String sslTest = "https://localhost:8443/ssl-test";
    
            ResponseEntity<String> response
                = restTemplate.getForEntity(sslTest, String.class);
    
            return "Outbound TLS " +
                (response.getStatusCode() == HttpStatus.OK ? "is" : "is not")  + " Working!!";
        }
    
        @GetMapping(value = "/exit")
        public void exit() {
            System.exit(0);
        }
    
    }
    
  3. Exécutez les commandes suivantes pour compiler le code et le empaqueter dans un fichier JAR exécutable.

    mvn clean package
    
  4. Chargez à nouveau l’application à l’aide de la même commande sftp décrite précédemment dans cet article.

    cd target
    sftp <your VM public IP address>
    put *.jar
    
  5. Exécutez l’application sur la machine virtuelle.

    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  6. Une fois que le serveur est en cours d’exécution, vérifiez qu’il accepte le certificat TLS/SSL. Dans le même interpréteur de commandes Bash que celui où vous avez émis la commande curl précédente, exécutez la commande suivante.

    curl --insecure https://<your VM public IP address>:8443/ssl-test-outbound
    

    Vous devriez voir le message Outbound TLS is working!!.

  7. Appelez le chemin exit pour arrêter le serveur et fermer les sockets réseau.

    curl --insecure https://<your VM public IP address>:8443/exit
    

Vous avez maintenant observé une illustration simple des actions charger, présenter et accepter avec un certificat TLS/SSL auto-signé stocké dans Azure Key Vault.

Déployer sur Azure Spring Apps

Maintenant que vous disposez de l’application Spring Boot en cours d’exécution localement, il est temps de le déplacer en production. Azure Spring Apps facilite le déploiement d’applications Spring Boot sur Azure sans aucune modification de code. Le service gère l’infrastructure des applications Spring, ce qui permet aux développeurs de se concentrer sur leur code. Azure Spring Apps assure la gestion du cycle de vie en utilisant des outils complets, tels que la supervision et les diagnostics, la gestion des configurations, la découverte de services, l’intégration CI/CD, les déploiements bleus-verts, etc. Pour déployer votre application sur Azure Spring Apps, consultez Déployer votre première application sur Azure Spring Apps.

Étapes suivantes

Pour en savoir plus sur Spring et Azure, poursuivez vers le centre de documentation Spring sur Azure.