次の方法で共有


Azure Key Vault 証明書を使用して Spring Boot で HTTPS を有効にする

このチュートリアルでは、Azure Key Vault と Azure リソースのマネージド ID を使用して、TLS/SSL 証明書を使用して Spring Boot (Azure Spring Apps を含む) アプリをセキュリティで保護する方法について説明します。

クラウドでもオンプレミスでも、運用グレードの Spring Boot アプリケーションでは、標準の TLS プロトコルを使用したネットワーク トラフィックに対してエンドツーエンドの暗号化が必要です。 見つかったほとんどの TLS/SSL 証明書は、パブリック ルート証明機関 (CA) から検出できます。 ただし、この検出が不可能な場合もあります。 証明書が検出できない場合、アプリには、そのような証明書を読み込み、受信ネットワーク接続に提示し、送信ネットワーク接続から受け入れる何らかの方法が必要です。

通常、Spring Boot アプリでは証明書をインストールして TLS を有効にします。 証明書は、Spring Boot アプリを実行している JVM のローカル キー ストアにインストールされます。 Spring on Azure では、証明書はローカルにインストールされません。 代わりに、Microsoft Azure の Spring 統合により、Azure Key Vault のヘルプと Azure リソースのマネージド ID を使用して TLS を有効にする安全で摩擦のない方法が提供されます。

このチュートリアルの要素の相互作用を示す図。

重要

現在、Spring Cloud Azure Certificate Starter バージョン 4.x 以降では TLS/mTLS はサポートされていません。Key Vault 証明書クライアントのみを自動構成します。 そのため、TLS/mTLS を使用する場合は、バージョン 4.x に移行できません。

前提 条件

  • Azure サブスクリプション - 無料アカウントを作成します

  • バージョン 11 でサポートされている Java Development Kit (JDK)

  • Apache Maven バージョン 3.0 以上。

  • Azure CLI

  • cURL または同様の HTTP ユーティリティ を使用して機能をテストします。

  • Azure 仮想マシン (VM) インスタンス。 ない場合は、az vm create コマンドと UbuntuServer によって提供される Ubuntu イメージを使用して、システム割り当てマネージド ID が有効になっている VM インスタンスを作成します。 システム割り当てマネージド ID に Contributor ロールを付与し、サブスクリプションへのアクセス scope を設定します。

  • Azure Key Vault インスタンス。 お持ちでない場合は、「クイック スタート: Azure portalを使用してキー コンテナーを作成する」を参照してください。

  • Spring Boot アプリケーション。 まだない場合は、Spring Initializrを使用して Maven プロジェクトを作成します。 Maven Project 選択し、依存関係の下で、Spring Web 依存関係を追加してから、Java バージョン 8 以降を選択してください。

重要

この記事の手順を完了するには、Spring Boot バージョン 2.5 以降が必要です。

自己署名 TLS/SSL 証明書を設定する

このチュートリアルの手順は、Azure Key Vault に直接格納されている TLS/SSL 証明書 (自己署名を含む) に適用されます。 自己署名証明書は運用環境での使用には適していませんが、開発およびテスト アプリケーションに役立ちます。

このチュートリアルでは、自己署名証明書を使用します。 証明書を設定するには、「クイック スタート: Azure portalを使用して Azure Key Vault から証明書を設定および取得する」を参照してください。

手記

証明書を設定した後、「Key Vault アクセス ポリシーを割り当てる」の手順に従って、Vm に Key Vault へのアクセス権を付与します。

TLS/SSL 証明書を使用したセキュリティで保護された接続

これで、VM と Key Vault インスタンスが作成され、Key Vault へのアクセス権が VM に付与されました。 次のセクションでは、Spring Boot アプリケーションで Azure Key Vault から TLS/SSL 証明書を介して安全に接続する方法について説明します。 このチュートリアルでは、次の 2 つのシナリオについて説明します。

  • セキュリティで保護された受信接続を使用して Spring Boot アプリケーションを実行する
  • 安全な送信接続を使用して Spring Boot アプリケーションを実行する

ヒント

次の手順では、コードが実行可能ファイルにパッケージ化され、VM にアップロードされます。 OpenJDK を VM にインストールすることを忘れないでください。

セキュリティで保護された受信接続を使用して Spring Boot アプリケーションを実行する

受信接続の TLS/SSL 証明書が Azure Key Vault から取得される場合は、次の手順に従ってアプリケーションを構成します。

  1. pom.xml ファイルに次の依存関係を追加します。

    <dependency>
       <groupId>com.azure.spring</groupId>
       <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId>
       <version>3.14.0</version>
    </dependency>
    
  2. application.properties 構成ファイルで Key Vault 資格情報を構成します。

    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>
    

    これらの値により、Spring Boot アプリは、チュートリアルの冒頭で説明したように、TLS/SSL 証明書の 読み込み アクションを実行できます。 次の表では、プロパティ値について説明します。

    財産 説明
    server.ssl.key-alias az keyvault certificate createに渡した --name 引数の値。
    server.ssl.key-store-type AzureKeyVaultである必要があります。
    server.ssl.trust-store-type AzureKeyVaultである必要があります。
    server.port HTTPS 接続をリッスンするローカル TCP ポート。
    azure.keyvault.uri az keyvault createから返される JSON の vaultUri プロパティ。 この値は環境変数に保存しました。

    Key Vault に固有の唯一のプロパティは azure.keyvault.uriです。 アプリは、システム割り当てマネージド ID に Key Vault へのアクセスが許可されている VM で実行されています。 そのため、アプリにもアクセス権が付与されています。

    これらの変更により、Spring Boot アプリで TLS/SSL 証明書を読み込むことができます。 次の手順では、チュートリアルの冒頭で説明したように、アプリが TLS/SSL 証明書の アクションを受け入れる を実行できるようにします。

  3. 次の内容が含まれるように、スタートアップ クラス ファイルを編集します。

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

    認証されていない REST GET 呼び出し内からの System.exit(0) の呼び出しは、デモンストレーションのみを目的としています。 実際のアプリケーションでは System.exit(0) を使用しないでください。

    このコードは、このチュートリアルの冒頭で言及された 現在の アクションを示しています。 次の一覧では、このコードに関するいくつかの詳細が強調表示されています。

    • Spring Initializr によって生成された SsltestApplication クラスに @RestController 注釈が追加されました。
    • @GetMapping の注釈がつけられたメソッドがあり、HTTP 呼び出し用の value が使用されています。
    • inbound メソッドは、ブラウザーが /ssl-test パスに対して HTTPS 要求を行うときに、単にあいさつ文を返します。 inbound メソッドは、サーバーが TLS/SSL 証明書をブラウザーに提示する方法を示しています。
    • exit メソッドを使用すると、JVM が呼び出されたときに終了します。 このメソッドは、このチュートリアルのコンテキストでサンプルを簡単に実行できるようにするための便利な方法です。
  4. 次のコマンドを実行してコードをコンパイルし、実行可能な JAR ファイルにパッケージ化します。

    mvn clean package
    
  5. <your-resource-group-name> 内に作成されたネットワーク セキュリティ グループで、IP アドレスからのポート 22 と 8443 の受信トラフィックが許可されていることを確認します。 受信トラフィックを許可するようにネットワーク セキュリティ グループの規則を構成する方法については、「ネットワーク セキュリティ グループの作成、変更、または削除 セキュリティ規則の操作」セクションを参照してください。

  6. 実行可能 JAR ファイルを VM に配置します。

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

    Spring Boot アプリをビルドして VM にアップロードしたので、次の手順に従って VM で実行し、curlで REST エンドポイントを呼び出します。

  7. SSH を使用して VM に接続し、実行可能 JAR を実行します。

    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  8. 新しい Bash シェルを開き、次のコマンドを実行して、サーバーが TLS/SSL 証明書を提示することを確認します。

    curl --insecure https://<your VM public IP address>:8443/ssl-test
    
  9. exit パスを呼び出してサーバーを強制終了し、ネットワーク ソケットを閉じます。

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

これで、自己署名 TLS/SSL 認定資格証を使用して読み込み提示アクションが確認できました。次は、アプリにいくつかの簡単な変更を加えて、受け入れアクションも確認します。

安全な送信接続を使用して Spring Boot アプリケーションを実行する

このセクションでは、送信接続の TLS/SSL 証明書が Azure Key Vault から取得されるように、前のセクションのコードを変更します。 その結果、Azure Key Vault からの '読み込み'、'提示'、および '受け入れ' アクションが満たされます。

  1. pom.xml ファイルに Apache HTTP クライアントの依存関係を追加します。

    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
       <version>4.5.13</version>
    </dependency>
    
  2. ssl-test-outboundという名前の新しい rest エンドポイントを追加します。 このエンドポイントは、それ自体に対して TLS ソケットを開き、TLS 接続が TLS/SSL 証明書を受け入れることを確認します。 スタートアップ クラスの前の部分を次のコードに置き換えます。

    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. 次のコマンドを実行してコードをコンパイルし、実行可能な JAR ファイルにパッケージ化します。

    mvn clean package
    
  4. この記事の前半と同じ sftp コマンドを使用して、アプリをもう一度アップロードします。

    cd target
    sftp <your VM public IP address>
    put *.jar
    
  5. VM でアプリを実行します。

    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  6. サーバーが実行されたら、サーバーが TLS/SSL 証明書を受け入れることを確認します。 前の curl コマンドを発行したのと同じ Bash シェルで、次のコマンドを実行します。

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

    Outbound TLS is working!!メッセージが表示されます。

  7. exit パスを呼び出してサーバーを強制終了し、ネットワーク ソケットを閉じます。

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

これで、Azure Key Vault に格納されている自己署名 TLS/SSL 証明書を使用して、'読み込み'、'提示'、および '受け入れ' アクションを簡単に確認できました。

Azure Spring Apps へのデプロイ

Spring Boot アプリケーションがローカルで実行されたので、運用環境に移行します。 Azure Spring Apps を すると、コードを変更することなく、Spring Boot アプリケーションを Azure に簡単にデプロイできます。 このサービスは、開発者が自分のコードに集中できるように、Spring アプリケーションのインフラストラクチャを管理します。 Azure Spring Apps では、包括的な監視と診断、構成管理、サービス検出、CI/CD 統合、ブルーグリーン デプロイなどを使用したライフサイクル管理が提供されます。 Azure Spring Apps にアプリケーションをデプロイするには、「初めてのアプリケーションを Azure Spring Appsにデプロイする」を参照してください。

次の手順

Spring と Azure の詳細については、Spring on Azure ドキュメント センターに進んでください。

Spring Cloud Azure Key Vault 証明書のサンプルSpring 開発者向けの Azure