【数据安全】教程:使用 Azure Key Vault 证书保护 Spring Boot 应用程序

本文涉及的产品
数据安全中心,免费版
简介: 本教程向你展示如何使用 Azure Key Vault 和 Azure 资源的托管标识通过 TLS/SSL 证书保护你的 Spring Boot(包括 Azure Spring 应用程序)应用程序。

本教程向你展示如何使用 Azure Key Vault 和 Azure 资源的托管标识通过 TLS/SSL 证书保护你的 Spring Boot(包括 Azure Spring 应用程序)应用程序。

生产级 Spring Boot 应用程序,无论是在云端还是在本地,都需要使用标准 TLS 协议对网络流量进行端到端加密。您遇到的大多数 TLS/SSL 证书都可以从公共根证书颁发机构 (CA) 中发现。然而,有时候,这种发现是不可能的。当证书不可发现时,应用程序必须有某种方式来加载此类证书,将它们呈现给入站网络连接,并从出站网络连接中接受它们。

Spring Boot 应用程序通常通过安装证书来启用 TLS。证书安装到运行 Spring Boot 应用程序的 JVM 的本地密钥库中。使用 Azure 上的 Spring,不会在本地安装证书。相反,Microsoft Azure 的 Spring 集成提供了一种安全且无摩擦的方式来借助 Azure Key Vault 和 Azure 资源的托管身份来启用 TLS。

在本教程中,您将学习如何:

  • 使用系统分配的托管标识创建 GNU/Linux VM
  • 创建 Azure Key Vault
  • 创建自签名 TLS/SSL 证书
  • 将自签名 TLS/SSL 证书存储在 Azure Key Vault 中
  • 运行 Spring Boot 应用程序,其中入站连接的 TLS/SSL 证书来自 Azure Key Vault
  • 运行 Spring Boot 应用程序,其中用于出站连接的 TLS/SSL 证书来自 Azure Key Vault

重要的

目前,Spring Cloud Azure Certificate starter 4.x 版本不支持 TLS/mTLS,它们仅自动配置 Key Vault 证书客户端。因此,如果要使用 TLS/mTLS,则无法迁移到版本 4.x。

先决条件

 

  • 如果您没有 Azure 订阅,请在开始之前创建一个免费帐户。
  • curl命令。大多数类 UNIX 操作系统都预装了此命令。特定于操作系统的客户端可在官方 curl 网站上获得。
  • jq 命令。大多数类 UNIX 操作系统都预装了此命令。官方 jq 网站上提供了特定于操作系统的客户端。
  • Azure CLI,版本 2.38 或更高版本
  • 受支持的 Java 开发工具包 (JDK),版本 8。有关详细信息,请参阅 Azure 和 Azure Stack 上的 Java 支持。
  • Apache Maven,版本 3.0。

重要的

完成本文中的步骤需要 Spring Boot 2.5 或更高版本。

使用系统分配的托管标识创建 GNU/Linux VM

使用以下步骤创建具有系统分配的托管标识的 Azure VM,并准备运行 Spring Boot 应用程序。有关 Azure 资源的托管标识的概述,请参阅什么是 Azure 资源的托管标识?。

  • 打开 Bash 外壳。
  • 注销并删除一些身份验证文件以删除任何挥之不去的凭据。

az logout

rm ~/.azure/accessTokens.json

rm ~/.azure/azureProfile.json

 

  • 登录到 Azure CLI。

 

az login

 

  • 设置订阅 ID。请务必将占位符替换为适当的值。

 

az account set -s <your subscription ID>

 

  • 创建 Azure 资源组。记下资源组名称以备后用。

 

az group create \

   --name <your resource group name> \

   --location <your resource group region>

 

  • 设置默认资源组。

az configure --defaults group=<your resource group name>

 

  • 使用 UbuntuServer 提供的映像 UbuntuLTS 创建启用了系统分配的托管标识的 VM 实例。

az vm create \

   --name <your VM name> \

   --debug \

   --generate-ssh-keys \

   --assign-identity \

   --role contributor \

   --scope /subscriptions/<your subscription> \

   --image UbuntuLTS \

   --admin-username azureuser

在 JSON 输出中,记下 publicIpAddress 和 systemAssignedIdentity 属性的值。您将在本教程的后面部分使用这些值。

笔记

UbuntuLTS 这个名字是统一资源名称 (URN) 的别名,它是为像 UbuntuLTS 这样的流行图像创建的缩写版本。运行以下命令以表格格式显示缓存的流行图像列表:

az vm image list --output table

 

  • 安装微软 OpenJDK。有关 OpenJDK 的完整信息,请参阅 Microsoft Build of OpenJDK。

ssh azureuser@<your VM public IP address>

 

  • 添加存储库。替换以下命令中的版本占位符并执行:

wget https://packages.microsoft.com/config/ubuntu/{version}/packages-microsoft-prod.deb -O packages-microsoft-prod.deb

sudo dpkg -i packages-microsoft-prod.deb

通过运行以下命令安装 Microsoft Build of OpenJDK:

sudo apt install apt-transport-https

sudo apt update

sudo apt install msopenjdk-11

 

创建和配置 Azure Key Vault

使用以下步骤创建 Azure Key Vault,并授予 VM 的系统分配托管标识访问 Key Vault 以获取证书的权限。

在资源组中创建 Azure Key Vault。

az keyvault create \

   --name <your Key Vault name> \

   --location <your resource group region>

export KEY_VAULT_URI=$(az keyvault show --name <your Key Vault name>

| jq -r '.properties.vaultUri')

记下 KEY_VAULT_URI 值。你稍后会用到它。

  • 授予 VM 使用证书密钥保管库的权限。

az keyvault set-policy \

   --name <your Key Vault name> \

   --object-id <your system-assigned identity> \

   --secret-permissions get list \

   --certificate-permissions get list import

创建并存储自签名 TLS/SSL 证书

本教程中的步骤适用于直接存储在 Azure Key Vault 中的任何 TLS/SSL 证书(包括自签名)。自签名证书不适合在生产中使用,但对开发和测试应用程序很有用。本教程使用自签名证书。要创建证书,请使用以下命令。

az keyvault certificate create \

   --vault-name <your Key Vault name> \

   --name mycert \

   --policy "$(az keyvault certificate get-default-policy)"

使用安全入站连接运行 Spring Boot 应用程序

在本部分中,你将创建一个 Spring Boot 入门应用程序,其中用于入站连接的 TLS/SSL 证书来自 Azure Key Vault。

要创建应用程序,请使用以下步骤:

Project: Maven Project


Language: Java


Spring Boot: 2.7.4


Group: com.contoso (You can put any valid Java package name here.)


Artifact: ssltest (You can put any valid Java class name here.)


Packaging: Jar


Java: 11

 

  • 选择添加依赖项....
  • 在文本字段中,键入 Spring Web 并按 Ctrl+Enter。
  • 在文本字段中键入 Azure Support,然后按 Enter。您的屏幕应如下所示。
  • 带有基本选项的 Spring Initializr 的屏幕截图。

  • 在页面底部,选择“生成”。
  • 出现提示时,将项目下载到本地计算机上的某个路径。本教程使用当前用户主目录中的 ssltest 目录。上面的值将为您提供该目录中的 ssltest.zip 文件。

启用 Spring Boot 应用程序以加载 TLS/SSL 证书

要使应用程序能够加载证书,请使用以下步骤:

  • 解压缩 ssltest.zip 文件。
  • 删除测试目录及其子目录。本教程忽略测试,因此您可以放心删除该目录。
  • 将 src/main/resources 中的 application.properties 重命名为 application.yml。
  • 文件布局如下所示。

├── HELP.md

├── mvnw

├── mvnw.cmd

├── pom.xml

└── src

   └── main

       ├── java

       │   └── com

       │       └── contoso

       │           └── ssltest

       │               └── SsltestApplication.java

       └── resources

           ├── application.yml

           ├── static

           └── templates

  • 修改 POM 以添加对 azure-spring-boot-starter-keyvault-certificates 的依赖。将以下代码添加到 pom.xml 文件的 <dependencies> 部分。

<dependency>

  <groupId>com.azure.spring</groupId>

  <artifactId>azure-spring-boot-starter-keyvault-certificates</artifactId>

</dependency>

 

  • 编辑 src/main/resources/application.yml 文件,使其具有以下内容。

server:

 ssl:

   key-alias: <the name of the certificate in Azure Key Vault to use>

   key-store-type: AzureKeyVault

   trust-store-type: AzureKeyVault

 port: 8443

azure:

 keyvault:

   uri: <the URI of the Azure Key Vault to use>

  • 这些值使 Spring Boot 应用程序能够执行 TLS/SSL 证书的加载操作,如本教程开头所述。下表描述了属性值。
Property Name Explanation
server.port The local TCP port on which to listen for HTTPS connections.
server.ssl.key-alias The value of the --name argument you passed to az keyvault certificate create.
server.ssl.key-store-type Must be AzureKeyVault.
server.ssl.trust-store-type Must be AzureKeyVault.
azure.keyvault.uri The vaultUri property in the return JSON from az keyvault create. You saved this value in an environment variable.

唯一特定于 Key Vault 的属性是 azure.keyvault.uri。该应用在其系统分配的托管标识已被授予访问 Key Vault 的 VM 上运行。因此,该应用程序也已被授予访问权限。

这些更改使 Spring Boot 应用程序能够加载 TLS/SSL 证书。在下一节中,您将允许应用程序执行 TLS/SSL 证书的接受操作,如本教程开头所述。

创建一个 Spring Boot REST 控制器

要创建 REST 控制器,请使用以下步骤:

  • 编辑 src/main/java/com/contoso/ssltest/SsltestApplication.java 文件,使其具有以下内容。

package com.contoso.ssltest;


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

   }


}

  1. 从未经身份验证的 REST GET 调用中调用 System.exit(0) 仅用于演示目的。不要在实际应用程序中使用 System.exit(0)。

此代码说明了本教程开头提到的当前操作。以下列表突出显示了有关此代码的一些详细信息:

  • 现在在 Spring Initializr 生成的 SsltestApplication 类上有一个 @RestController 注释。
  • 有一个用@GetMapping 注释的方法,其中包含您将进行的HTTP 调用的值。
  • 当浏览器向 /ssl-test 路径发出 HTTPS 请求时,入站方法只返回一条问候语。 inbound 方法说明了服务器如何向浏览器提供 TLS/SSL 证书。
  • exit 方法将导致 JVM 在被调用时退出。此方法有助于使示例易于在本教程的上下文中运行。
  • 打开一个新的 Bash shell 并导航到 ssltest 目录。运行以下命令。

 

mvn clean package

 

  1. Maven 编译代码并将其打包成可执行的 JAR 文件

验证在 <您的资源组名称> 中创建的网络安全组是否允许来自您的 IP 地址的端口 22 和 8443 上的入站流量。要了解如何配置网络安全组规则以允许入站流量,请参阅创建、更改或删除网络安全组的使用安全规则部分。

  • 将可执行 JAR 文件放在 VM 上。

cd target

sftp azureuser@<your VM public IP address>

put *.jar

在服务器上运行应用程序

现在您已经构建了 Spring Boot 应用程序并将其上传到 VM,请使用以下步骤在 VM 上运行它并使用 curl 调用 REST 端点。

  1. 使用 SSH 连接到 VM,然后运行可执行 jar。

set -o noglob

ssh azureuser@<your VM public IP address> "java -jar *.jar"

  1. 打开一个新的 Bash shell 并执行以下命令以验证服务器是否提供 TLS/SSL 证书。

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

  1. 调用退出路径以终止服务器并关闭网络套接字。

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

 

现在您已经看到使用自签名 TLS/SSL 证书加载和呈现操作,您将对应用程序进行一些微不足道的更改以查看接受操作。

使用安全出站连接运行 Spring Boot 应用程序

在本节中,你将修改上一节中的代码,以便出站连接的 TLS/SSL 证书来自 Azure Key Vault。因此,从 Azure Key Vault 中可以满足加载、呈现和接受操作。

修改 SsltestApplication 以说明出站 TLS 连接

 

使用以下步骤修改应用程序:

  • 通过将以下代码添加到 pom.xml 文件的 <dependencies> 部分来添加对 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 证书。

用以下代码替换 SsltestApplication.java 的内容。

package com.contoso.ssltest;


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

   }


}

  • 构建应用程序。

cd ssltest

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 shell 中,运行以下命令。

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

您应该会看到消息出站 TLS 正在工作!!。

  • 调用退出路径以终止服务器并关闭网络套接字。

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

 

你现在已经看到了一个简单的说明,说明了使用存储在 Azure Key Vault 中的自签名 TLS/SSL 证书进行加载、呈现和接受操作。

清理资源

使用完本教程中创建的 Azure 资源后,可以使用以下命令删除它们:

az group delete --name <your resource group name>


Tags

本文:https://architect.pub/tutorial-secure-spring-boot-apps-using-azure-key-vault-certificates

相关文章
|
2月前
|
监控 Java API
Spring Boot 3.2 结合 Spring Cloud 微服务架构实操指南 现代分布式应用系统构建实战教程
Spring Boot 3.2 + Spring Cloud 2023.0 微服务架构实践摘要 本文基于Spring Boot 3.2.5和Spring Cloud 2023.0.1最新稳定版本,演示现代微服务架构的构建过程。主要内容包括: 技术栈选择:采用Spring Cloud Netflix Eureka 4.1.0作为服务注册中心,Resilience4j 2.1.0替代Hystrix实现熔断机制,配合OpenFeign和Gateway等组件。 核心实操步骤: 搭建Eureka注册中心服务 构建商品
393 3
|
8月前
|
人工智能 Java API
Java也能快速搭建AI应用?一文带你玩转Spring AI可落地性
Java语言凭借其成熟的生态与解决方案,特别是通过 Spring AI 框架,正迅速成为 AI 应用开发的新选择。本文将探讨如何利用 Spring AI Alibaba 构建在线聊天 AI 应用,并实现对其性能的全面可观测性。
1963 114
|
23天前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
232 4
|
1月前
|
存储 安全 Java
如何在 Spring Web 应用程序中使用 @SessionScope 和 @RequestScope
Spring框架中的`@SessionScope`和`@RequestScope`注解用于管理Web应用中的状态。`@SessionScope`绑定HTTP会话生命周期,适用于用户特定数据,如购物车;`@RequestScope`限定于单个请求,适合无状态、线程安全的操作,如日志记录。合理选择作用域能提升应用性能与可维护性。
|
2月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
2月前
|
安全 算法 Java
在Spring Boot中应用Jasypt以加密配置信息。
通过以上步骤,可以在Spring Boot应用中有效地利用Jasypt对配置信息进行加密,这样即使配置文件被泄露,其中的敏感信息也不会直接暴露给攻击者。这是一种在不牺牲操作复杂度的情况下提升应用安全性的简便方法。
734 10
|
3月前
|
安全 Java Nacos
0代码改动实现Spring应用数据库帐密自动轮转
Nacos作为国内被广泛使用的配置中心,已经成为应用侧的基础设施产品,近年来安全问题被更多关注,这是中国国内软件行业逐渐迈向成熟的标志,也是必经之路,Nacos提供配置加密存储-运行时轮转的核心安全能力,将在应用安全领域承担更多职责。
|
3月前
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
406 2
|
3月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
367 13
|
8月前
|
存储 人工智能 开发框架
Spring AI Alibaba 应用框架挑战赛圆满落幕,恭喜获奖选手
第二届开放原子大赛 Spring AI Alibaba 应用框架挑战赛决赛于 2 月 23 日在北京圆满落幕。
326 113