使用 Azure Key Vault 憑證在 Spring Boot 中啟用 HTTPS
本教學課程說明如何使用 Azure Key Vault 和 Azure 資源的受控識別,使用 TLS/SSL 憑證來保護 Spring Boot(包括 Azure Spring Apps)應用程式。
生產等級的 Spring Boot 應用程式,無論是在雲端還是內部部署,都需要使用標準 TLS 通訊協定進行網路流量的端對端加密。 您遇到的大部分 TLS/SSL 憑證都可以從公用根憑證授權機構(CA)尋找到。 不過,有時候無法進行此探索。 當憑證無法被發現時,應用程式必須有某種方式來讀取這些憑證,並將它們呈現給入站網路連線,並從出站網路連線接受憑證。
Spring Boot 應用程式通常會藉由安裝憑證來啟用 TLS。 憑證會安裝到執行 Spring Boot 應用程式的 JVM 本機密鑰存放區。 在 Azure 上使用 Spring 時,憑證不會安裝在本機。 相反地,Microsoft Azure 的 Spring 整合提供了安全且無摩擦的方式,可透過 Azure Key Vault 和 Azure 資源的受控識別來啟用 TLS。
重要
目前,Spring Cloud Azure 憑證入門 4.x 版或更新版本不支援 TLS/mTLS,它們只會自動設定 Key Vault 憑證用戶端。 因此,如果您想要使用 TLS/mTLS,則無法移轉至 4.x 版。
先決條件
Azure 訂用帳戶 - 建立一個免費的訂用帳戶。
第 11 版支援的 Java 開發工具套件 (JDK)。
Apache Maven 3.0 版或更高版本。
cURL 或類似的 HTTP 公用程式來測試功能。
Azure 虛擬機 (VM) 實例。 如果您沒有虛擬機器,請使用 az vm create 命令及 UbuntuServer 提供的 Ubuntu 映像,建立已啟用系統指派的受控身分識別的 VM 實例。 將
Contributor
角色授與系統指派的受控識別,然後將存取scope
設定為您的訂用帳戶。Azure Key Vault 實例。 如果您沒有金鑰儲存庫,請參閱 快速入門:使用 Azure 入口網站建立金鑰保存庫。
Spring Boot 應用程式。 如果您還沒有 Maven 專案,請使用 Spring Initializr來建立一個 Maven 專案。 請務必選取 Maven 專案,然後在 [相依性] 底下,新增 Spring Web 相依性,然後選取 [Java 第 8 版] 或更新版本。
重要
需要 Spring Boot 2.5 版或更高版本,才能完成本文中的步驟。
設定自我簽署 TLS/SSL 憑證
本教學課程中的步驟適用於直接儲存在 Azure Key Vault 中的任何 TLS/SSL 憑證(包括自我簽署)。 自我簽署憑證不適用於生產環境,但對開發和測試應用程式很有用。
本教學課程使用自我簽署憑證。 若要設定憑證,請參閱 快速入門:使用 Azure 入口網站從 Azure Key Vault 設定及擷取憑證。
注意
設定憑證之後,請依照 中的指示來將密鑰保存庫的存取原則指派給,以授予虛擬機器 (VM) 訪問 Key Vault 的權限。
透過 TLS/SSL 憑證保護連線
您現在有 VM 和金鑰保存庫的實例,並已授予該 VM 對金鑰保存庫的存取權限。 下列各節說明如何在 Spring Boot 應用程式中透過來自 Azure Key Vault 的 TLS/SSL 憑證安全地連線。 本教學課程示範下列兩個案例:
- 執行具有安全輸入連線的 Spring Boot 應用程式
- 執行具有安全輸出連線的 Spring Boot 應用程式
提示
在下列步驟中,程式代碼會封裝成可執行檔,並上傳至 VM。 別忘了在 VM 中安裝 OpenJDK。
執行具有安全輸入連線的 Spring Boot 應用程式
當輸入連線的 TLS/SSL 憑證來自 Azure Key Vault 時,請遵循下列步驟來設定應用程式:
將下列相依性新增至 pom.xml 檔案:
<dependency> <groupId>com.azure.spring</groupId> <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId> <version>3.14.0</version> </dependency>
在 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
您傳遞給 --name
的az keyvault certificate create
參數的值。server.ssl.key-store-type
必須是 AzureKeyVault
。server.ssl.trust-store-type
必須是 AzureKeyVault
。server.port
要接聽 HTTPS 連線的本機 TCP 連接埠。 azure.keyvault.uri
vaultUri
傳回的 JSON 中的az keyvault create
屬性。 您已將此值儲存在環境變數中。Key Vault 特有的唯一屬性是
azure.keyvault.uri
。 應用程式正在一個虛擬機器上執行,而該虛擬機器的系統指派身分已獲授予金鑰保存庫的存取權。 因此,應用程式也已獲得存取權。這些變更可讓 Spring Boot 應用程式載入 TLS/SSL 憑證。 在下一個步驟中,您將讓應用程式執行 接受 TLS/SSL 憑證的 動作,如教學課程開頭所述。
編輯啟動類別檔案,使其具有下列內容。
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 生成的
@RestController
類別上有SsltestApplication
註解。 - 有一個以
@GetMapping
標註的方法,並附有您進行的 HTTP 呼叫的相關描述value
。 - 當瀏覽器向
inbound
路徑提出 HTTPS 要求時,/ssl-test
方法只會傳回問候語。inbound
方法說明伺服器如何將 TLS/SSL 憑證呈現給瀏覽器。 -
exit
方法會導致 JVM 在叫用時結束。 此方法旨在提高便利性,使範例能在本教學內容中輕鬆執行。
- 現在,Spring Initializr 生成的
執行下列命令來編譯程序代碼,並將其封裝成可執行的 JAR 檔案。
mvn clean package
確認在
<your-resource-group-name>
中建立的網路安全組允許來自您的IP位址的端口 22 和 8443 的輸入流量。 若要瞭解如何設定網路安全組規則以允許輸入流量,請參閱 建立、變更或刪除網路安全組內的 使用安全性規則 一節。將可執行檔 JAR 檔案放在 VM 上。
cd target sftp azureuser@<your VM public IP address> put *.jar
既然您已建置 Spring Boot 應用程式並將其上傳至 VM,請使用下列步驟在 VM 上執行,並使用
curl
呼叫 REST 端點。使用 SSH 連線到 VM,然後執行可執行的 JAR。
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
開啟新的 Bash 殼層,然後執行下列命令來確認伺服器是否顯示 TLS/SSL 憑證。
curl --insecure https://<your VM public IP address>:8443/ssl-test
叫用
exit
路徑來終止伺服器並關閉網路插孔。curl --insecure https://<your VM public IP address>:8443/exit
既然您已看到 載入,並 使用自我簽署的 TLS/SSL 憑證呈現 動作,請對應用程式進行一些微不足道的變更,以查看 接受 動作。
執行具有安全輸出連線的 Spring Boot 應用程式
在本節中,您會修改上一節中的程式代碼,讓輸出連線的 TLS/SSL 憑證來自 Azure Key Vault。 因此,Azure Key Vault 會滿足 載入、呈現,以及 接受 的動作。
將 Apache HTTP 用戶端相依性新增至您的 pom.xml 檔案:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
新增名為
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); } }
執行下列命令來編譯程序代碼,並將其封裝成可執行的 JAR 檔案。
mvn clean package
使用本文稍早的相同
sftp
命令,再次上傳應用程式。cd target sftp <your VM public IP address> put *.jar
在 VM 上執行應用程式。
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
執行伺服器之後,請確認伺服器接受 TLS/SSL 憑證。 在發出上一個
curl
命令的同一個 Bash 殼層中,執行下列命令。curl --insecure https://<your VM public IP address>:8443/ssl-test-outbound
您應該看到訊息
Outbound TLS is working!!
。叫用
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,請繼續前往 Azure 上的 Spring 檔中心。