Habilitar HTTPS no Spring Boot com certificados do Cofre de Chaves do Azure
Este tutorial mostra como proteger seus aplicativos Spring Boot (incluindo o Azure Spring Apps) com certificados TLS/SSL usando o Cofre de Chaves do Azure e identidades gerenciadas para recursos do Azure.
Os aplicativos Spring Boot de nível de produção, sejam eles na nuvem ou locais, exigem criptografia de ponta a ponta para tráfego de rede usando protocolos TLS padrão. A maioria dos certificados TLS/SSL encontrados é detectável por meio de uma AC (autoridade de certificação) raiz pública. Às vezes, no entanto, essa descoberta não é possível. Quando os certificados não são detectáveis, o aplicativo precisa ter alguma forma de carregar esses certificados, apresentá-los a conexões de rede de entrada e aceitá-los nas conexões de rede de saída.
Os aplicativos Spring Boot geralmente habilitam o TLS instalando os certificados. Os certificados são instalados no repositório de chaves local da JVM que está executando o aplicativo Spring Boot. Com o Spring no Azure, os certificados não são instalados localmente. Em vez disso, a integração do Spring para o Microsoft Azure fornece um modo seguro e fácil de habilitar o TLS com a ajuda do Azure Key Vault e da identidade gerenciada para recursos do Azure.
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ê deseja usar TLS/mTLS, você não pode migrar para a versão 4.x.
Pré-requisitos
Uma assinatura do Azure – crie uma gratuitamente.
Um JDK (Kit de Desenvolvimento do Java) com suporte na versão 11.
Apache Maven, versão 3.0 ou superior.
O 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
Contributor
função à identidade gerenciada atribuída pelo sistema e defina o acessoscope
à 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. Caso não tiver um, crie um projeto Maven com o Spring Initializr. Certifique-se de selecionar Projeto Maven e, em Dependências, adicione a dependência do 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 deste artigo.
Definir um certificado TLS/SSL auto-assinado
As etapas neste tutorial se aplicam a qualquer certificado TLS/SSL (incluindo autoassinado) armazenado diretamente no Azure Key Vault. Os certificados autoassinados não são adequados para uso na 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 de Chaves do Azure usando o portal do Azure.
Observação
Depois de definir o certificado, conceda acesso VM ao Cofre de Chaves seguindo as instruções em Atribuir uma política de acesso ao Cofre de Chaves.
Conexão segura através de certificado TLS/SSL
Agora você tem uma VM e uma instância do Cofre de Chaves e concedeu à VM acesso ao Cofre de Chaves. As seções a seguir mostram como se conectar com segurança por meio de certificados TLS/SSL do Cofre de Chaves do Azure no aplicativo Spring Boot. Este tutorial demonstra os dois cenários a seguir:
- Executar um aplicativo Spring Boot com conexões de entrada seguras
- Executar um aplicativo Spring Boot com conexões de saída seguras
Dica
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 o OpenJDK na VM.
Executar 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:
Adicione as seguintes dependências ao arquivo pom.xml :
<dependency> <groupId>com.azure.spring</groupId> <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId> <version>3.14.0</version> </dependency>
Configure as credenciais do Cofre de Chaves no arquivo de configuração 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>
Esses valores permitem que o aplicativo Spring Boot execute a ação load para o certificado TLS/SSL, conforme mencionado no início do tutorial. A tabela a seguir descreve os valores da propriedade.
Propriedade Descrição server.ssl.key-alias
O valor do argumento --name
que você passou paraaz 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 as conexões HTTPS. azure.keyvault.uri
A propriedade vaultUri
do JSON de retorno deaz keyvault create
. Você salvou esse valor em uma variável de ambiente.A única propriedade específica ao Key Vault é
azure.keyvault.uri
. O aplicativo está em execução em uma VM cuja identidade gerenciada atribuída pelo sistema recebeu acesso ao Key Vault. 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 de aceitação para o certificado TLS/SSL, conforme mencionado no início do tutorial.
Edite o arquivo de classe de inicialização para que ele tenha o seguinte conteúdo.
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); } }
A chamada a
System.exit(0)
em uma chamada GET REST não autenticada serve apenas para fins de demonstração. Não useSystem.exit(0)
em um aplicativo real.Esse código ilustra a ação present mencionada no início deste tutorial. A seguinte lista realça alguns detalhes sobre este código:
- Agora há uma anotação
@RestController
na classeSsltestApplication
gerada pelo Spring Initializr. - Há um método anotado com , com
@GetMapping
umvalue
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étodoinbound
ilustra como o servidor apresenta o certificado TLS/SSL para o navegador. - O
exit
método faz com que a JVM saia quando invocada. Esse método é uma conveniência para facilitar a execução da amostra no contexto deste tutorial.
- Agora há uma anotação
Execute os seguintes comandos para compilar o código e empacotá-lo em um arquivo JAR executável.
mvn clean package
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 do seu endereço IP. Para saber mais sobre como configurar as regras do grupo de segurança de rede para permitir o tráfego de entrada, confira a seção Trabalhar com regras de segurança em Criar, alterar ou excluir um grupo de segurança de rede.Coloque o arquivo JAR executável na VM.
cd target sftp azureuser@<your VM public IP address> put *.jar
Agora que você criou o aplicativo Spring Boot e o carregou na VM, use as etapas a seguir para executá-lo na VM e chamar o ponto de extremidade REST com
curl
.Use SSH para se conectar à VM e execute o JAR executável.
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
Abra um novo shell do Bash e execute o comando a seguir para verificar se o servidor apresenta o certificado TLS/SSL.
curl --insecure https://<your VM public IP address>:8443/ssl-test
Invoque o caminho
exit
para encerrar o servidor e fechar os soquetes de rede.curl --insecure https://<your VM public IP address>:8443/exit
Agora que você viu as ações de carregamento e apresentação com um certificado TLS/SSL autoassinado, faça algumas alterações triviais no aplicativo para ver a ação de aceitação também.
Executar 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 de Chaves do Azure. Portanto, as ações load, present e accept são satisfeitas no Azure Key Vault.
Adicione a dependência do cliente Apache HTTP ao arquivo pom.xml :
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
Adicione um novo ponto de extremidade REST chamado
ssl-test-outbound
. Esse ponto de extremidade abre um soquete TLS para ele mesmo e verifica se a conexão TLS aceita o certificado TLS/SSL. Substitua a parte anterior da classe de inicialização com o código a seguir.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); } }
Execute os seguintes comandos para compilar o código e empacotá-lo em um arquivo JAR executável.
mvn clean package
Carregue o aplicativo novamente com o mesmo comando
sftp
usado anteriormente neste artigo.cd target sftp <your VM public IP address> put *.jar
Execute o aplicativo na VM.
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
Depois que o servidor estiver em execução, verifique se o servidor aceita o certificado TLS/SSL. No mesmo shell do Bash em que você emitiu o comando
curl
anterior, execute o comando a seguir.curl --insecure https://<your VM public IP address>:8443/ssl-test-outbound
Você deve ver a mensagem
Outbound TLS is working!!
.Invoque o caminho
exit
para encerrar o servidor e fechar os soquetes de rede.curl --insecure https://<your VM public IP address>:8443/exit
Agora você observou uma ilustração simples das ações load, present e accept com um certificado TLS/SSL autoassinado armazenado no Azure Key Vault.
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. Os Aplicativos Spring do Azure facilitam a implantação de aplicativos Spring Boot no Azure sem alterações de código. O serviço gerencia a infraestrutura dos aplicativos do Spring para que os desenvolvedores possam se concentrar no código. O Azure Spring Apps fornece gerenciamento de ciclo de vida usando monitoramento e diagnóstico abrangentes, gerenciamento de configuração, descoberta de serviços, integração de CI/CD, implantações em “blue-green” e muito mais. Para implantar seu aplicativo nos Aplicativos Spring do Azure, consulte Implantar seu primeiro aplicativo nos Aplicativos Spring do Azure.
Próximas etapas
Para saber mais sobre o Spring e o Azure, continue no Spring no Centro de Documentação do Azure.