Udostępnij za pośrednictwem


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ść certyfikatów TLS/SSL, które napotykasz, jest dostępna z publicznego nadrzędnego 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.

Diagram przedstawiający interakcję elementów w tym samouczku.

Ważny

Obecnie starter Azure Spring Cloud Certificate w wersji 4.x lub nowszej nie obsługuje protokołów TLS/mTLS, automatycznie konfiguruje tylko klienta certyfikatów 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.

Warunki wstępne

  • Subskrypcja platformy Azure — utwórz ją bezpłatnie.

  • Obsługiwany zestaw Java Development Kit (JDK) w wersji 11.

  • Apache Maven w wersji 3.0 lub nowszej.

  • Azure CLI.

  • cURL lub podobne narzędzie HTTP do testowania funkcji.

  • Instancja maszyny wirtualnej Azure. Jeśli go nie masz, użyj polecenia az vm create i obrazu systemu Ubuntu dostarczonego przez serwer UbuntuServer, aby utworzyć wystąpienie maszyny wirtualnej z włączoną tożsamością zarządzaną przypisaną przez system. Udziel roli Contributor zarządzanej przez system tożsamości, a następnie skonfiguruj poziom dostępu scope do subskrypcji.

  • Instancja usługi Azure Key Vault. Jeśli go nie masz, zobacz Szybki start: tworzenie magazynu kluczy przy użyciu portalu Azure.

  • Aplikacja Spring Boot. Jeśli go nie masz, utwórz projekt Maven przy użyciu Spring Initializr. Pamiętaj, aby wybrać Projekt Maven, a w części Dependenciesdodać zależność Spring Web, a następnie wybrać wersję Java 8 lub nowszą.

Ważny

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.

Notatka

Po ustawieniu certyfikatu przyznaj maszynie wirtualnej dostęp do usługi Key Vault, postępując zgodnie z instrukcjami w Przypisywanie zasad dostępu usługi Key Vault.

Bezpieczne połączenie za pośrednictwem certyfikatu TLS/SSL

Teraz masz wirtualną maszynę i instancję usługi Key Vault oraz udzieliłeś wirtualnej maszynie 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ć 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:

  1. 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>
    
  2. 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łasność Opis
    server.ssl.key-alias Wartość argumentu --name przekazanego do az keyvault certificate create.
    server.ssl.key-store-type Musi być AzureKeyVault.
    server.ssl.trust-store-type Musi być 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 z az keyvault create. Tę wartość zapisano w zmiennej środowiskowej.

    Jedyną właściwością specyficzną dla Key Vault jest azure.keyvault.uri. Aplikacja działa na maszynie wirtualnej, której systemowo przypisana tożsamość zarządzana ma przyznane uprawnienia 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ła akcję zaakceptować dla certyfikatu TLS/SSL, jak wspomniano na początku samouczka.

  3. 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 odbywa się tylko w celach demonstracyjnych. Nie używaj System.exit(0) w rzeczywistej aplikacji.

    Ten kod ilustruje obecną akcję wymienioną na początku tego samouczka. Poniższa lista zawiera kilka szczegółów dotyczących tego kodu:

    • Istnieje teraz adnotacja @RestController w klasie SsltestApplication wygenerowanej przez narzędzie Spring Initializr.
    • Istnieje metoda oznaczona jako @GetMapping, z value dla wykonywanego wywołania HTTP.
    • Metoda inbound po prostu zwraca powitanie, gdy przeglądarka wysyła żądanie HTTPS do ścieżki /ssl-test. Metoda inbound ilustruje, w jaki sposób serwer przedstawia certyfikat TLS/SSL w przeglądarce.
    • Metoda exit powoduje zakończenie działania maszyny wirtualnej JVM po wywołaniu. Ta metoda ułatwia uruchomienie przykładu w kontekście tego samouczka.
  4. Uruchom następujące polecenia, aby skompilować kod i spakować go do wykonywalnego pliku JAR.

    mvn clean package
    
  5. Sprawdź, czy sieciowa grupa zabezpieczeń utworzona w <your-resource-group-name> zezwala na ruch przychodzący na portach 22 i 8443 z twojego adresu IP. Aby dowiedzieć się więcej na temat konfigurowania reguł sieciowej grupy zabezpieczeń w celu zezwalania na ruch przychodzący, zobacz sekcję Work with security rules (Praca z regułami zabezpieczeń) w Tworzenie, zmienianie lub usuwanie sieciowej grupy zabezpieczeń.

  6. 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 przy użyciu curl.

  7. 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"
    
  8. Otwórz nową powłokę Bash i wykonaj następujące polecenie, aby zweryfikować, czy serwer prezentuje certyfikat TLS/SSL.

    curl --insecure https://<your VM public IP address>:8443/ssl-test
    
  9. Wywołaj ścieżkę exit, aby zabić serwer i zamknąć gniazda sieciowe.

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

Po tym jak zobaczysz wczytywanie i prezentację działań z własnym certyfikatem TLS/SSL, wprowadź drobne zmiany do aplikacji, aby również zobaczyć działanie przyjęcia.

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 akcje ładowania z, obecności zoraz akceptacji z są spełniane z Azure Key Vault.

  1. 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>
    
  2. Dodaj nowy punkt końcowy rest o nazwie ssl-test-outbound. Ten punkt końcowy otwiera gniazdo TLS do samego siebie 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);
        }
    
    }
    
  3. Uruchom następujące polecenia, aby skompilować kod i spakować go do wykonywalnego pliku JAR.

    mvn clean package
    
  4. Prześlij aplikację ponownie przy użyciu tego samego polecenia sftp, jak wcześniej w artykule.

    cd target
    sftp <your VM public IP address>
    put *.jar
    
  5. Uruchom aplikację na maszynie wirtualnej.

    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  6. Po uruchomieniu serwera sprawdź, czy serwer akceptuje certyfikat TLS/SSL. W tej samej powłoce Bash, w której wydano poprzednie polecenie curl, 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!!.

  7. Wywołaj ścieżkę exit, aby zabić serwer i zamknąć gniazda sieciowe.

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

Teraz widziałeś prostą ilustrację ładowania , obecności i akceptacji akcji z certyfikatem TLS/SSL z podpisem własnym przechowywanym w usłudze Azure Key Vault.

Wdrażanie w Azure Spring Apps

Teraz, gdy aplikacja Spring Boot działa lokalnie, nadszedł czas, aby przenieść ją do środowiska produkcyjnego. 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 z CI/CD, wdrożeń blue-green i wielu innych funkcji. Aby wdrożyć aplikację w usłudze Azure Spring Apps, zobacz Deploy your first application to Azure Spring Apps(Wdrażanie pierwszej aplikacji w usłudze Azure Spring Apps).

Następne kroki

Aby dowiedzieć się więcej na temat platformy Spring i platformy Azure, przejdź do Centrum dokumentacji platformy Azure.