Azure Key Vault 인증서를 사용하여 Spring Boot에서 HTTPS 사용
이 자습서에서는 Azure Key Vault 및 Azure 리소스에 대한 관리 ID를 사용하여 TLS/SSL 인증서로 Spring Boot(Azure Spring Apps 포함) 앱을 보호하는 방법을 보여 줍니다.
클라우드 또는 온-프레미스에서 프로덕션 등급 Spring Boot 애플리케이션은 표준 TLS 프로토콜을 사용하는 네트워크 트래픽에 대한 엔드투엔드 암호화가 필요합니다. 대부분의 TLS/SSL 인증서는 공용 루트 CA(인증 기관)에서 검색할 수 있습니다. 그러나 때때로 이러한 발견이 불가능할 수도 있습니다. 인증서를 검색할 수 없는 경우 앱은 이러한 인증서를 로드하고, 인바운드 네트워크 연결에 표시하고, 아웃바운드 네트워크 연결에서 수락할 수 있는 방법이 있어야 합니다.
Spring Boot 앱은 일반적으로 인증서를 설치하여 TLS를 사용하도록 설정합니다. 인증서는 Spring Boot 앱을 실행하는 JVM의 로컬 키 저장소에 설치됩니다. Spring on Azure에서는 인증서가 로컬로 설치되지 않습니다. 대신 Microsoft Azure에 대한 Spring 통합은 Azure Key Vault 및 Azure 리소스에 대한 관리 ID의 도움을 받아 TLS를 사용하도록 설정하는 안전하고 마찰 없는 방법을 제공합니다.
이 자습서의 요소 상호 작용을 보여 주는
중요하다
현재 Spring Cloud Azure Certificate Starter 버전 4.x 이상은 TLS/mTLS를 지원하지 않으며 Key Vault 인증서 클라이언트만 자동으로 구성합니다. 따라서 TLS/mTLS를 사용하려는 경우 버전 4.x로 마이그레이션할 수 없습니다.
필수 구성 요소
Azure 구독 - 무료만들
있습니다. 버전 11에서 지원되는 JDK(Java Development Kit).
Apache Maven 버전 3.0 이상.
cURL 또는 유사한 HTTP 유틸리티를 사용하여 기능을 테스트합니다.
Azure VM(가상 머신) 인스턴스입니다. 없는 경우, UbuntuServer에서 제공하는 Ubuntu 이미지를 사용하여 시스템 할당 관리 ID가 활성화된 VM 인스턴스를 만들기 위해 az vm create 명령어를 사용하세요. 시스템에 할당된 관리 ID에
Contributor
역할을 부여한 후, 구독 수준에서scope
액세스를 설정합니다.Azure Key Vault 인스턴스입니다. 하나가 없는 경우, "빠른 시작: Azure Portal을 사용하여 키 자격 증명 모음 만들기"를 참조하세요.
Spring Boot 애플리케이션입니다. 없는 경우 Spring Initializr사용하여 Maven 프로젝트를 만듭니다. 반드시 Maven 프로젝트
을 선택한 후 종속성 아래에Spring Web 종속성을 추가하고, Java 버전 8 이상을 선택하세요.
중요하다
이 문서의 단계를 완료하려면 Spring Boot 버전 2.5 이상이 필요합니다.
자체 서명된 TLS/SSL 인증서 설정
이 자습서의 단계는 Azure Key Vault에 직접 저장된 TLS/SSL 인증서(자체 서명 포함)에 적용됩니다. 자체 서명된 인증서는 프로덕션 환경에서 사용하기에는 적합하지 않지만 개발 및 테스트 애플리케이션에 유용합니다.
이 자습서에서는 자체 서명된 인증서를 사용합니다. 인증서를 설정하려면 빠른 시작: Azure Portal을 사용하여 Azure Key Vault에서 인증서를 설정하고 검색하기를 참조하세요.
메모
인증서를 설정한 후 Key Vault 액세스 정책할당의 지침에 따라 VM에 Key Vault에 대한 액세스 권한을 부여합니다.
TLS/SSL 인증서를 통한 보안 연결
이제 VM 및 Key Vault 인스턴스가 있으며 Key Vault에 대한 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
az keyvault create
반환 JSON의vaultUri
속성입니다. 이 값을 환경 변수에 저장했습니다.Key Vault와 관련된 유일한 속성은
azure.keyvault.uri
. 앱이 시스템 할당 관리 ID에 Key Vault에 대한 액세스 권한이 부여된 VM에서 실행되고 있습니다. 따라서 앱에 액세스 권한도 부여되었습니다.이러한 변경 내용을 통해 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에서 생성된
SsltestApplication
클래스에@RestController
주석이 있습니다. - HTTP 호출을 수행할 때
value
을 사용하여@GetMapping
주석이 달린 메서드가 있습니다. -
inbound
메서드는 브라우저에서/ssl-test
경로에 대한 HTTPS 요청을 할 때 인사말만 반환합니다.inbound
메서드는 서버가 브라우저에 TLS/SSL 인증서를 제공하는 방법을 보여 줍니다. -
exit
메서드를 사용하면 JVM이 호출될 때 종료됩니다. 이 메서드는 이 자습서의 컨텍스트에서 샘플을 쉽게 실행할 수 있도록 하는 편리한 방법입니다.
- 이제 Spring Initializr에서 생성된
다음 명령을 실행하여 코드를 컴파일하고 실행 가능한 JAR 파일로 패키지합니다.
mvn clean package
<your-resource-group-name>
내에서 만든 네트워크 보안 그룹이 IP 주소의 포트 22 및 8443에서 인바운드 트래픽을 허용하는지 확인합니다. 인바운드 트래픽을 허용하도록 네트워크 보안 그룹 규칙을 구성하는 방법에 대한 자세한 내용은 보안 규칙 작업네트워크 보안 그룹만들기, 변경 또는 삭제 섹션을 참조하세요.VM에 실행 파일 JAR 파일을 배치합니다.
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에서 충족됩니다.
pom.xml 파일에 Apache HTTP 클라이언트 종속성을 추가합니다.
<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에 대해 자세히 알아보려면 Spring on Azure 설명서 센터를 계속 진행하세요.
Spring 개발자용 Azure