Включение 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. Сертификаты устанавливаются в локальном хранилище ключей виртуальной машины Java, где выполняется приложение 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. Если у вас его нет, см. краткое руководство. Создание хранилища ключей с помощью портал Azure.
Приложение Spring Boot. Если у вас его нет, создайте проект Maven с помощью Spring Initializr. Обязательно выберите проект Maven и в разделе "Зависимости" добавьте зависимость 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, настройте приложение, выполнив следующие действия.
Добавьте следующие зависимости в xml-файл 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, как упоминалось в начале этого учебника. В следующей таблице описаны значения свойств.
Свойство Description 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)
в настоящих приложениях.Этот код иллюстрирует действие предоставления, упомянутое в начале этого учебника. В указанном ниже списке приведены некоторые сведения об этом коде.
- Теперь с помощью Spring Initializr создана аннотация
@RestController
для классаSsltestApplication
. - Существует метод, аннотированный с
@GetMapping
помощьюvalue
вызова HTTP. - Метод
inbound
просто возвращает приветствие, когда браузер выполняет HTTPS-запрос для пути/ssl-test
. Методinbound
показывает, как сервер предоставляет сертификат TLS/SSL для браузера. - Метод
exit
приводит к выходу JVM при вызове. Этот метод позволяет упростить выполнение примера в контексте этого учебника.
- Теперь с помощью Spring Initializr создана аннотация
Выполните следующие команды, чтобы скомпилировать код и упаковать его в исполняемый 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-подключение сертификат 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.