Włączanie protokołu HTTPS w rozwiązaniu Spring Boot przy użyciu certyfikatów usługi Azure Key Vault
W tym samouczku przedstawiono sposób zabezpieczania aplikacji Spring Boot (w tym usługi Azure Spring Apps) przy użyciu certyfikatów TLS/SSL przy użyciu usługi Azure Key Vault i tożsamości zarządzanych dla zasobów platformy Azure.
Aplikacje Spring Boot klasy produkcyjnej, zarówno w chmurze, jak i lokalnie, wymagają kompleksowego szyfrowania ruchu sieciowego przy użyciu standardowych protokołów TLS. Większość napotkanych certyfikatów TLS/SSL jest wykrywalnych z publicznego głównego urzędu certyfikacji. Czasami jednak to odnajdywanie nie jest możliwe. Jeśli certyfikaty nie są wykrywalne, aplikacja musi mieć jakiś sposób na załadowanie takich certyfikatów, przedstawienie ich przychodzącym połączeniom sieciowym i zaakceptowanie ich z wychodzących połączeń sieciowych.
Aplikacje Spring Boot zwykle włączają protokół TLS, instalując certyfikaty. Certyfikaty są instalowane w lokalnym magazynie kluczy maszyny wirtualnej JVM z uruchomioną aplikacją Spring Boot. W przypadku platformy Spring na platformie Azure certyfikaty nie są instalowane lokalnie. Zamiast tego integracja platformy Spring dla platformy Microsoft Azure zapewnia bezpieczny i bezproblemowy sposób włączania protokołu TLS z pomocą usługi Azure Key Vault i tożsamości zarządzanej dla zasobów platformy Azure.
Ważne
Obecnie szablon startowy certyfikatu platformy Azure spring Cloud w wersji 4.x lub nowszej nie obsługuje protokołu TLS/mTLS, automatycznie konfigurują tylko klienta certyfikatu usługi Key Vault. W związku z tym, jeśli chcesz użyć protokołu TLS/mTLS, nie możesz przeprowadzić migracji do wersji 4.x.
Wymagania wstępne
Subskrypcja platformy Azure — utwórz bezpłatnie.
Obsługiwany zestaw Java Development Kit (JDK) w wersji 11.
Apache Maven w wersji 3.0 lub nowszej.
cURL lub podobne narzędzie HTTP do testowania funkcjonalności.
Wystąpienie maszyny wirtualnej platformy Azure. Jeśli go nie masz, użyj polecenia az vm create i obrazu systemu Ubuntu dostarczonego przez ubuntuServer, aby utworzyć wystąpienie maszyny wirtualnej z włączoną tożsamością zarządzaną przypisaną przez system.
Contributor
Udziel roli tożsamości zarządzanej przypisanej przez system, a następnie ustaw dostępscope
do subskrypcji.Wystąpienie usługi Azure Key Vault. Jeśli go nie masz, zobacz Szybki start: tworzenie magazynu kluczy przy użyciu witryny Azure Portal.
Aplikacja Spring Boot. Jeśli go nie masz, utwórz projekt Maven za pomocą narzędzia Spring Initializr. Pamiętaj, aby wybrać pozycję Projekt Maven i w obszarze Zależności dodaj zależność Spring Web , a następnie wybierz pozycję Java w wersji 8 lub nowszej.
Ważne
Do wykonania kroków opisanych w tym artykule jest wymagany program Spring Boot w wersji 2.5 lub nowszej.
Ustawianie certyfikatu TLS/SSL z podpisem własnym
Kroki opisane w tym samouczku dotyczą dowolnego certyfikatu TLS/SSL (w tym z podpisem własnym) przechowywanego bezpośrednio w usłudze Azure Key Vault. Certyfikaty z podpisem własnym nie są odpowiednie do użycia w środowisku produkcyjnym, ale są przydatne w przypadku aplikacji deweloperskich i testowych.
W tym samouczku jest używany certyfikat z podpisem własnym. Aby ustawić certyfikat, zobacz Szybki start: ustawianie i pobieranie certyfikatu z usługi Azure Key Vault przy użyciu witryny Azure Portal.
Uwaga
Po ustawieniu certyfikatu przyznaj maszynie wirtualnej dostęp do usługi Key Vault, postępując zgodnie z instrukcjami w temacie Przypisywanie zasad dostępu do usługi Key Vault.
Bezpieczne połączenie za pośrednictwem certyfikatu TLS/SSL
Masz teraz maszynę wirtualną i wystąpienie usługi Key Vault oraz udzielono maszynie wirtualnej dostępu do usługi Key Vault. W poniższych sekcjach pokazano, jak bezpiecznie łączyć się za pośrednictwem certyfikatów TLS/SSL z usługi Azure Key Vault w aplikacji Spring Boot. W tym samouczku przedstawiono następujące dwa scenariusze:
- Uruchamianie aplikacji Spring Boot z bezpiecznymi połączeniami przychodzącymi
- Uruchamianie aplikacji Spring Boot z bezpiecznymi połączeniami wychodzącymi
Napiwek
W poniższych krokach kod zostanie spakowany do pliku wykonywalnego i przekazany do maszyny wirtualnej. Nie zapomnij zainstalować zestawu OpenJDK na maszynie wirtualnej.
Uruchamianie aplikacji Spring Boot z bezpiecznymi połączeniami przychodzącymi
Gdy certyfikat TLS/SSL dla połączenia przychodzącego pochodzi z usługi Azure Key Vault, skonfiguruj aplikację, wykonując następujące kroki:
Dodaj następujące zależności do pliku pom.xml :
<dependency> <groupId>com.azure.spring</groupId> <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId> <version>3.14.0</version> </dependency>
Skonfiguruj poświadczenia usługi Key Vault w pliku konfiguracji 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>
Te wartości umożliwiają aplikacji Spring Boot wykonywanie akcji ładowania dla certyfikatu TLS/SSL, jak wspomniano na początku samouczka. W poniższej tabeli opisano wartości właściwości.
Właściwości opis server.ssl.key-alias
Wartość argumentu przekazanego --name
doaz keyvault certificate create
elementu .server.ssl.key-store-type
Musi mieć wartość AzureKeyVault
.server.ssl.trust-store-type
Musi mieć wartość AzureKeyVault
.server.port
Lokalny port TCP, na którym można nasłuchiwać połączeń HTTPS. azure.keyvault.uri
Właściwość vaultUri
w zwracaniu kodu JSON zaz keyvault create
. Tę wartość zapisano w zmiennej środowiskowej.Jedyną właściwością specyficzną dla usługi Key Vault jest
azure.keyvault.uri
. Aplikacja jest uruchomiona na maszynie wirtualnej, której tożsamość zarządzana przypisana przez system została udzielona dostępu do usługi Key Vault. W związku z tym aplikacja również uzyskała dostęp.Te zmiany umożliwiają aplikacji Spring Boot ładowanie certyfikatu TLS/SSL. W następnym kroku włączysz aplikację, aby wykonać akcję akceptowania certyfikatu TLS/SSL, jak wspomniano na początku samouczka.
Edytuj plik klasy uruchamiania, aby miał następującą zawartość.
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); } }
Wywoływanie
System.exit(0)
z poziomu nieuwierzytelnionego wywołania REST GET służy tylko do celów demonstracyjnych. Nie używajSystem.exit(0)
w rzeczywistej aplikacji.Ten kod ilustruje bieżącą akcję wymienioną na początku tego samouczka. Poniższa lista zawiera kilka szczegółów dotyczących tego kodu:
- Na klasie wygenerowanej
SsltestApplication
przez spring initializr jest teraz@RestController
adnotacja. - Istnieje metoda oznaczona adnotacją z elementem
@GetMapping
, z elementemvalue
dla wywołania HTTP, które wykonujesz. - Metoda
inbound
po prostu zwraca powitanie, gdy przeglądarka wysyła żądanie HTTPS do ścieżki/ssl-test
. Metodainbound
ilustruje, w jaki sposób serwer przedstawia certyfikat TLS/SSL w przeglądarce. - Metoda
exit
powoduje zamknięcie maszyny JVM po wywołaniu. Ta metoda jest wygodą, aby przykład był łatwy do uruchomienia w kontekście tego samouczka.
- Na klasie wygenerowanej
Uruchom następujące polecenia, aby skompilować kod i spakować go do wykonywalnego pliku JAR.
mvn clean package
Sprawdź, czy sieciowa grupa zabezpieczeń utworzona w ramach
<your-resource-group-name>
programu zezwala na ruch przychodzący na portach 22 i 8443 z adresu IP. Aby dowiedzieć się więcej o konfigurowaniu reguł sieciowej grupy zabezpieczeń w celu zezwalania na ruch przychodzący, zobacz sekcję Praca z regułami zabezpieczeń w sekcji Tworzenie, zmienianie lub usuwanie sieciowej grupy zabezpieczeń.Umieść plik JAR wykonywalny na maszynie wirtualnej.
cd target sftp azureuser@<your VM public IP address> put *.jar
Teraz, gdy aplikacja Spring Boot została skompilowana i przekazana do maszyny wirtualnej, wykonaj następujące kroki, aby uruchomić ją na maszynie wirtualnej i wywołać punkt końcowy REST za pomocą polecenia
curl
.Użyj protokołu SSH, aby nawiązać połączenie z maszyną wirtualną, a następnie uruchom wykonywalny plik JAR.
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
Otwórz nową powłokę Bash i wykonaj następujące polecenie, aby sprawdzić, czy serwer przedstawia certyfikat TLS/SSL.
curl --insecure https://<your VM public IP address>:8443/ssl-test
Wywołaj ścieżkę
exit
, aby zabić serwer i zamknąć gniazda sieciowe.curl --insecure https://<your VM public IP address>:8443/exit
Teraz, po wyświetleniu obciążenia i przedstawieniu akcji z certyfikatem TLS/SSL z podpisem własnym, wprowadź pewne proste zmiany w aplikacji, aby zobaczyć również akcję akceptowania.
Uruchamianie aplikacji Spring Boot z bezpiecznymi połączeniami wychodzącymi
W tej sekcji zmodyfikujesz kod w poprzedniej sekcji, tak aby certyfikat TLS/SSL dla połączeń wychodzących pochodził z usługi Azure Key Vault. W związku z tym obciążenie, obecność i akceptowanie akcji są spełnione w usłudze Azure Key Vault.
Dodaj zależność klienta HTTP apache do pliku pom.xml :
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
Dodaj nowy punkt końcowy rest o nazwie
ssl-test-outbound
. Ten punkt końcowy otwiera samo gniazdo PROTOKOŁU TLS i sprawdza, czy połączenie TLS akceptuje certyfikat TLS/SSL. Zastąp poprzednią część klasy startowej następującym kodem.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); } }
Uruchom następujące polecenia, aby skompilować kod i spakować go do wykonywalnego pliku JAR.
mvn clean package
Przekaż aplikację ponownie przy użyciu tego samego
sftp
polecenia z wcześniejszej sekcji tego artykułu.cd target sftp <your VM public IP address> put *.jar
Uruchom aplikację na maszynie wirtualnej.
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
Po uruchomieniu serwera sprawdź, czy serwer akceptuje certyfikat TLS/SSL. W tej samej powłoce powłoki Bash, w której wydano poprzednie
curl
polecenie, uruchom następujące polecenie.curl --insecure https://<your VM public IP address>:8443/ssl-test-outbound
Powinien zostać wyświetlony komunikat
Outbound TLS is working!!
.Wywołaj ścieżkę
exit
, aby zabić serwer i zamknąć gniazda sieciowe.curl --insecure https://<your VM public IP address>:8443/exit
Zaobserwowano teraz prostą ilustrację obciążenia, prezentowania i akceptowania akcji z certyfikatem TLS/SSL z podpisem własnym przechowywanym w usłudze Azure Key Vault.
Wdrażanie w usłudze Azure Spring Apps
Teraz, gdy aplikacja Spring Boot działa lokalnie, nadszedł czas, aby przenieść ją do środowiska produkcyjnego. Usługa Azure Spring Apps ułatwia wdrażanie aplikacji Spring Boot na platformie Azure bez żadnych zmian w kodzie. Usługa zarządza infrastrukturą aplikacji Spring, aby deweloperzy mogli skupić się na swoim kodzie. Usługa Azure Spring Apps zapewnia zarządzanie cyklem życia przy użyciu kompleksowego monitorowania i diagnostyki, zarządzania konfiguracją, odnajdywania usług, integracji/ciągłego wdrażania, wdrożeń niebieskich zielonych i nie tylko. Aby wdrożyć aplikację w usłudze Azure Spring Apps, zobacz Wdrażanie pierwszej aplikacji w usłudze Azure Spring Apps.
Następne kroki
Aby dowiedzieć się więcej na temat oprogramowania Spring i platformy Azure, przejdź do centrum dokumentacji dotyczącej oprogramowania Spring na platformie Azure.