Включение HTTPS в Spring Boot с помощью сертификатов Azure Key Vault
В этом руководстве показано, как защитить приложения Spring Boot (включая Azure Spring Apps) с помощью TLS/SSL-сертификатов с помощью Azure Key Vault и управляемых удостоверений для ресурсов Azure.
Для рабочих приложений Spring Boot, будь то в облаке или локальной среде, требуется сквозное шифрование сетевого трафика с использованием стандартных протоколов TLS. Большинство сертификатов TLS/SSL, с которыми вы сталкиваетесь, доступны для обнаружения у общедоступного корневого центра сертификации (ЦС). Однако иногда это обнаружение невозможно. Если сертификаты недоступны для обнаружения, приложение должно иметь какой-то способ загрузки таких сертификатов, представить их для входящих сетевых подключений и принять их из исходящих сетевых подключений.
Приложения Spring Boot обычно разрешают TLS, устанавливая сертификаты. Сертификаты устанавливаются в локальное хранилище ключей JVM, на котором выполняется приложение Spring Boot. При использовании Spring в Azure сертификаты не устанавливаются локально. Вместо этого интеграция Spring для Microsoft Azure обеспечивает безопасный и беспрепятственный способ включения TLS с помощью Azure Key Vault и управляемой идентификации для ресурсов Azure.
Важный
В настоящее время стартер для сертификатов в Azure Spring Cloud версий 4.x или более поздних не поддерживает TLS/mTLS, он автоматически настраивает клиента сертификатов Key Vault. Таким образом, если вы хотите использовать TLS/mTLS, вы не можете перенести его в версию 4.x.
Необходимые условия
Подписка Azure — оформите ее бесплатно.
Поддерживаемый пакет средств разработки Java (JDK) с версией 11.
Apache Maven версии 3.0 или более поздней.
cURL или аналогичную программу HTTP для тестирования функциональных возможностей.
Экземпляр виртуальной машины Azure. Если у вас его нет, используйте команду az vm create и образ Ubuntu, предоставленный UbuntuServer, для создания экземпляра виртуальной машины с включенным управляемым удостоверением, назначаемым системой. Предоставьте роль
Contributor
управляемому удостоверению, назначаемому системой, затем установите уровень доступаscope
для вашей подписки.Экземпляр Azure Key Vault. Если у вас его нет, ознакомьтесь с кратким руководством по . Создание хранилища ключей с помощью портала Azure.
Приложение Spring Boot. Если у вас его нет, создайте проект Maven с помощью Spring Initializr. Обязательно выберите Maven Project и в разделе зависимости, добавьте зависимость Spring Web, а затем выберите Java версии 8 или более поздней.
Важный
Для выполнения действий, описанных в этой статье, требуется spring Boot версии 2.5 или более поздней.
Настройка самозаверяющего TLS/SSL-сертификата
Действия, описанные в этом руководстве, применяются к любому СЕРТИФИКАТу TLS/SSL (включая самозаверяющий сертификат), хранящийся непосредственно в Azure Key Vault. Самозаверяющий сертификат не подходит для использования в рабочей среде, но полезен для разработки и тестирования приложений.
В этом руководстве используется самоподписанный сертификат. Чтобы настроить сертификат, см. краткое руководство : Настройка и получение сертификата из Azure Key Vault с помощью портала Azure.
Заметка
После установки сертификата предоставьте виртуальной машине доступ к Key Vault, следуя инструкциям в Назначить политику доступа Key Vault.
Безопасное подключение через TLS/SSL-сертификат
Теперь у вас есть виртуальная машина и экземпляр Key Vault, и виртуальная машина получила доступ к Key Vault. В следующих разделах показано, как безопасно подключаться через TLS/SSL-сертификаты из Azure Key Vault в приложении Spring Boot. В этом руководстве показаны следующие два сценария:
- Запуск приложения Spring Boot с безопасными входящими подключениями
- Запуск приложения Spring Boot с безопасными исходящими подключениями
Совет
В следующих шагах код будет упаковен в исполняемый файл и отправлен на виртуальную машину. Не забудьте установить 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>
Настройте учетные данные Key Vault в файле конфигурации 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>
Эти значения позволяют приложению 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
Локальный TCP-порт, на котором выполняется прослушивание HTTPS-подключений. azure.keyvault.uri
Свойство vaultUri
в возвращаемом JSON отaz keyvault create
. Вы сохранили это значение в переменной среды.Единственным свойством, характерным для Key Vault, является
azure.keyvault.uri
. Приложение запущено на виртуальной машине, которой предоставлено системно назначенное управляемое удостоверение для доступа к Key Vault. Поэтому приложению также предоставлен доступ.Эти изменения позволяют приложению 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); } }
Вызов
System.exit(0)
из неавторентированного вызова REST GET предназначен только для демонстрационных целей. Не используйтеSystem.exit(0)
в реальном приложении.Этот код иллюстрирует представленное действие, упомянутое в начале этого руководства. В следующем списке приведены некоторые сведения об этом коде:
- Теперь на классе
SsltestApplication
, созданном Spring Initializr, присутствует аннотация@RestController
. - Существует метод, аннотированный с
@GetMapping
, сvalue
для вызываемого HTTP-вызова. - Метод
inbound
возвращает приветствие, когда браузер обращается с HTTPS-запросом к пути/ssl-test
. Методinbound
иллюстрирует, как сервер представляет TLS/SSL-сертификат браузеру. - Метод
exit
приводит к выходу JVM при вызове. Этот метод удобен для упрощения выполнения примера в контексте этого руководства.
- Теперь на классе
Выполните следующие команды, чтобы скомпилировать код и упаковать его в исполняемый JAR-файл.
mvn clean package
Убедитесь, что группа безопасности сети, созданная в
<your-resource-group-name>
, разрешает входящий трафик через порты 22 и 8443 с вашего IP-адреса. Сведения о настройке правил группы безопасности сети для разрешения входящего трафика см. в разделе Работа с правилами безопасности раздела Создание, изменение или удаление группы безопасности сети.Поместите исполняемый JAR-файл на виртуальную машину.
cd target sftp azureuser@<your VM public IP address> put *.jar
Теперь, когда вы создали приложение Spring Boot и отправили его на виртуальную машину, выполните следующие действия, чтобы запустить его на виртуальной машине и вызвать конечную точку REST с
curl
.Используйте SSH для подключения к виртуальной машине, а затем запустите исполняемый 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.
Добавьте зависимость клиента Apache HTTP в файл pom.xml:
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency>
Добавьте новую конечную точку REST с именем
ssl-test-outbound
. Эта конечная точка открывает сокет 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
Запустите приложение на виртуальной машине.
set -o noglob ssh azureuser@<your VM public IP address> "java -jar *.jar"
После запуска сервера убедитесь, что сервер принимает TLS/SSL-сертификат. В той же оболочке Bash, где вы выпустили предыдущую команду
curl
, выполните следующую команду.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
Теперь вы наблюдали простую иллюстрацию действий загрузки, присутствияи принятия с использованием самозаверяющего сертификата TLS/SSL, хранящегося в Azure Key Vault.
Развертывание в 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 в Azure.