Ler em inglês

Partilhar via


Habilitar HTTPS no Spring Boot com certificados do Azure Key Vault

Este tutorial mostra como proteger seus aplicativos Spring Boot (incluindo Azure Spring Apps) com certificados TLS/SSL usando o Azure Key Vault e identidades gerenciadas para recursos do Azure.

Os aplicativos Spring Boot de nível de produção, seja na nuvem ou no local, exigem criptografia de ponta a ponta para o tráfego de rede usando protocolos TLS padrão. A maioria dos certificados TLS/SSL que você encontra são detetáveis a partir de uma autoridade de certificação (CA) raiz pública. Às vezes, no entanto, essa descoberta não é possível. Quando os certificados não são detetáveis, o aplicativo deve ter alguma maneira de carregar esses certificados, apresentá-los a conexões de rede de entrada e aceitá-los de conexões de rede de saída.

Os aplicativos Spring Boot normalmente habilitam o TLS instalando os certificados. Os certificados são instalados no armazenamento de chaves local da JVM que está executando o aplicativo Spring Boot. Com o Spring on Azure, os certificados não são instalados localmente. Em vez disso, a integração do Spring para Microsoft Azure fornece uma maneira segura e sem atrito de habilitar o TLS com a ajuda do Cofre de Chaves do Azure e identidade gerenciada para recursos do Azure.

Diagrama mostrando a interação dos elementos neste tutorial.

Importante

Atualmente, o Spring Cloud Azure Certificate starter versão 4.x ou superior não oferece suporte a TLS/mTLS, eles apenas configuram automaticamente o cliente de certificado do Cofre de Chaves. Portanto, se você quiser usar TLS/mTLS, não poderá migrar para a versão 4.x.

Pré-requisitos

  • Uma assinatura do Azure - crie uma gratuitamente.

  • Um Kit de Desenvolvimento Java (JDK) suportado com a versão 11.

  • Apache Maven versão 3.0 ou superior.

  • CLI do Azure.

  • cURL ou um utilitário HTTP semelhante para testar a funcionalidade.

  • Uma instância de máquina virtual (VM) do Azure. Se você não tiver um, use o comando az vm create e a imagem do Ubuntu fornecida pelo UbuntuServer para criar uma instância de VM com uma identidade gerenciada atribuída pelo sistema habilitada. Conceda a função Contributor à identidade gerenciada atribuída ao sistema e defina o scope de acesso à sua assinatura.

  • Uma instância do Azure Key Vault. Se você não tiver um, consulte Guia de início rápido: criar um cofre de chaves usando o portal do Azure.

  • Um aplicativo Spring Boot. Se você não tiver um, crie um projeto Maven com o Spring Initializr. Certifique-se de selecionar do Projeto Maven e, em Dependências, adicione a dependência Spring Web e, em seguida, selecione Java versão 8 ou superior.

Importante

O Spring Boot versão 2.5 ou superior é necessário para concluir as etapas neste artigo.

Definir um certificado TLS/SSL autoassinado

As etapas neste tutorial se aplicam a qualquer certificado TLS/SSL (incluindo autoassinado) armazenado diretamente no Cofre da Chave do Azure. Os certificados autoassinados não são adequados para uso em produção, mas são úteis para aplicativos de desenvolvimento e teste.

Este tutorial usa um certificado autoassinado. Para definir o certificado, consulte Guia de início rápido: definir e recuperar um certificado do Cofre da Chave do Azure usando o portal do Azure.

Nota

Depois de configurar o certificado, conceda acesso da VM ao Cofre de Chaves seguindo as instruções em política de acesso ao Cofre de Chaves.

Conexão segura através do certificado TLS/SSL

Agora você tem uma VM e uma instância do Cofre da Chave e concedeu à VM acesso ao Cofre da Chave. As seções a seguir mostram como se conectar com segurança por meio de certificados TLS/SSL do Azure Key Vault no aplicativo Spring Boot. Este tutorial demonstra os dois cenários a seguir:

  • Execute um aplicativo Spring Boot com conexões de entrada seguras
  • Execute um aplicativo Spring Boot com conexões de saída seguras

Sugestão

Nas etapas a seguir, o código será empacotado em um arquivo executável e carregado na VM. Não se esqueça de instalar OpenJDK na VM.

Execute um aplicativo Spring Boot com conexões de entrada seguras

Quando o certificado TLS/SSL para a conexão de entrada vier do Cofre de Chaves do Azure, configure o aplicativo seguindo estas etapas:

  1. Adicione as seguintes dependências ao seu arquivo pom.xml:

    XML
    <dependency>
       <groupId>com.azure.spring</groupId>
       <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId>
       <version>3.14.0</version>
    </dependency>
    
  2. Configure as credenciais do Cofre da Chave no ficheiro de configuração application.properties.

    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>
    

    Esses valores permitem que o aplicativo Spring Boot execute a ação de carregamento de para o certificado TLS/SSL, conforme mencionado no início do tutorial. A tabela a seguir descreve os valores das propriedades.

    Propriedade Descrição
    server.ssl.key-alias O valor do argumento --name que você passou para az keyvault certificate create.
    server.ssl.key-store-type Deve ser AzureKeyVault.
    server.ssl.trust-store-type Deve ser AzureKeyVault.
    server.port A porta TCP local na qual escutar conexões HTTPS.
    azure.keyvault.uri A propriedade vaultUri do retorno JSON de az keyvault create. Você salvou esse valor em uma variável de ambiente.

    A única propriedade específica do Key Vault é azure.keyvault.uri. O aplicativo está sendo executado em uma VM cuja identidade gerenciada atribuída ao sistema recebeu acesso ao Cofre da Chave. Portanto, o aplicativo também recebeu acesso.

    Essas alterações permitem que o aplicativo Spring Boot carregue o certificado TLS/SSL. Na próxima etapa, você habilitará o aplicativo para executar a ação aceitar para o certificado TLS/SSL, conforme mencionado no início do tutorial.

  3. Edite o arquivo de classe de inicialização para que ele tenha o seguinte conteúdo.

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

    Chamar System.exit(0) de dentro de uma chamada REST GET não autenticada é apenas para fins de demonstração. Não use System.exit(0) em um aplicativo real.

    Este código ilustra a ação presente mencionada no início deste tutorial. A lista a seguir destaca alguns detalhes sobre esse código:

    • Agora há uma @RestController anotação na classe SsltestApplication gerada pelo Spring Initializr.
    • Há um método anotado com @GetMapping, com um value para a chamada HTTP que você faz.
    • O método inbound simplesmente retorna uma saudação quando um navegador faz uma solicitação HTTPS para o caminho /ssl-test. O método inbound ilustra como o servidor apresenta o certificado TLS/SSL ao navegador.
    • O método exit faz com que a JVM saia quando invocada. Esse método é uma conveniência para tornar o exemplo fácil de executar no contexto deste tutorial.
  4. Execute os seguintes comandos para compilar o código e empacotá-lo em um arquivo JAR executável.

    Bash
    mvn clean package
    
  5. Verifique se o grupo de segurança de rede criado no <your-resource-group-name> permite o tráfego de entrada nas portas 22 e 8443 a partir do seu endereço IP. Para saber mais sobre como configurar regras de grupo de segurança de rede para permitir tráfego de entrada, consulte a seção Trabalhar com regras de segurança de Criar, alterar ou excluir um grupo de segurança de rede.

  6. Coloque o arquivo JAR executável na VM.

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

    Agora que você criou o aplicativo Spring Boot e o carregou para a VM, use as etapas a seguir para executá-lo na VM e chamar o ponto de extremidade REST com curl.

  7. Use SSH para se conectar à VM e, em seguida, execute o JAR executável.

    Bash
    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  8. Abra um novo shell Bash e execute o seguinte comando para verificar se o servidor apresenta o certificado TLS/SSL.

    Bash
    curl --insecure https://<your VM public IP address>:8443/ssl-test
    
  9. Invoque o caminho exit para matar o servidor e fechar os soquetes de rede.

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

Agora que viste o carregar e o apresentar ações com um certificado TLS/SSL autoassinado, faz algumas alterações triviais na aplicação para veres a ação de aceitar também.

Execute um aplicativo Spring Boot com conexões de saída seguras

Nesta seção, você modifica o código na seção anterior para que o certificado TLS/SSL para conexões de saída venha do Cofre da Chave do Azure. Portanto, o carregar, apresentare aceitar ações são satisfeitas a partir do Cofre de Chaves do Azure.

  1. Adicione a dependência do cliente HTTP Apache ao seu arquivo pom.xml:

    XML
    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
       <version>4.5.13</version>
    </dependency>
    
  2. Adicione um novo ponto de extremidade de repouso chamado ssl-test-outbound. Esse ponto de extremidade abre um soquete TLS para si mesmo e verifica se a conexão TLS aceita o certificado TLS/SSL. Substitua a parte anterior da classe de inicialização pelo código a seguir.

    Java
    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. Execute os seguintes comandos para compilar o código e empacotá-lo em um arquivo JAR executável.

    Bash
    mvn clean package
    
  4. Carregue o aplicativo novamente usando o mesmo comando sftp do início deste artigo.

    Bash
    cd target
    sftp <your VM public IP address>
    put *.jar
    
  5. Execute o aplicativo na VM.

    Bash
    set -o noglob
    ssh azureuser@<your VM public IP address> "java -jar *.jar"
    
  6. Depois que o servidor estiver em execução, verifique se o servidor aceita o certificado TLS/SSL. No mesmo shell Bash onde você emitiu o comando curl anterior, execute o seguinte comando.

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

    Deverá ver a mensagem Outbound TLS is working!!.

  7. Invoque o caminho exit para matar o servidor e fechar os soquetes de rede.

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

Agora você observou uma ilustração simples do carregar, apresentare aceitar ações com um certificado TLS/SSL autoassinado armazenado no Cofre de Chaves do Azure.

Implantar no Azure Spring Apps

Agora que você tem o aplicativo Spring Boot em execução localmente, é hora de movê-lo para a produção. do Azure Spring Apps facilita a implantação de aplicativos Spring Boot no Azure sem alterações de código. O serviço gerencia a infraestrutura dos aplicativos Spring para que os desenvolvedores possam se concentrar em seu código. O Azure Spring Apps fornece gerenciamento do ciclo de vida usando monitoramento e diagnóstico abrangentes, gerenciamento de configuração, descoberta de serviços, integração de CI/CD, implantações azul-verde e muito mais. Para implantar seu aplicativo no Azure Spring Apps, consulte Implantar seu primeiro aplicativo no Azure Spring Apps.

Próximos passos

Para saber mais sobre o Spring e o Azure, continue para o centro de documentação do Spring on Azure.