【数据安全】教程:使用 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

相关文章
|
1天前
|
存储 JSON 前端开发
利用Spring MVC开发程序2
利用Spring MVC开发程序
10 1
|
1天前
|
设计模式 JSON 前端开发
利用Spring MVC开发程序1
利用Spring MVC开发程序
11 0
|
1天前
|
前端开发 IDE Java
构建一个基于React和Spring Boot的简易聊天室应用
构建一个基于React和Spring Boot的简易聊天室应用
6 0
|
6天前
|
Java 关系型数据库 Docker
docker打包部署spring boot应用(mysql+jar+Nginx)
docker打包部署spring boot应用(mysql+jar+Nginx)
|
7天前
|
Java Maven Docker
Docker化Spring Boot3应用:从镜像构建到部署
本文介绍了如何在Linux上通过命令行构建和运行Spring Boot 3服务的Docker镜像。首先,基于Ubuntu创建包含JDK 21的基础镜像,然后使用Maven打包Spring Boot应用。接着,构建服务镜像,将应用和依赖添加到镜像中,并设置工作目录和暴露端口。最后,利用docker-compose部署服务,挂载宿主机目录以方便更新静态文件。Docker简化了应用部署,确保了不同环境的一致性。
49 2
Docker化Spring Boot3应用:从镜像构建到部署
|
8天前
|
Cloud Native Java 关系型数据库
【阿里云云原生专栏】构建云原生应用:基于Spring Boot与阿里云服务的全栈指南
【5月更文挑战第21天】构建云原生应用是企业数字化转型的关键,本文提供了一份基于Spring Boot和阿里云的全栈指南。涵盖从阿里云账号注册、ECS与Docker搭建,到Spring Boot项目创建、业务代码编写和部署。此外,还介绍了如何集成阿里云OSS存储、RDS数据库服务以及ACK容器服务,助力打造高效、可扩展和易管理的云原生应用。
129 3
|
14天前
|
前端开发 Java 测试技术
Java一分钟之Spring MVC:构建Web应用
【5月更文挑战第15天】Spring MVC是Spring框架的Web应用模块,基于MVC模式实现业务、数据和UI解耦。常见问题包括:配置DispatcherServlet、Controller映射错误、视图解析未设置、Model数据传递遗漏、异常处理未配置、依赖注入缺失和忽视单元测试。解决这些问题可提升代码质量和应用性能。注意配置`web.xml`、`@RequestMapping`、`ViewResolver`、`Model`、`@ExceptionHandler`、`@Autowired`,并编写测试用例。
306 3
|
14天前
|
开发框架 监控 Java
深入探索Spring Boot的监控、管理和测试功能及实战应用
【5月更文挑战第14天】Spring Boot是一个快速开发框架,提供了一系列的功能模块,包括监控、管理和测试等。本文将深入探讨Spring Boot中监控、管理和测试功能的原理与应用,并提供实际应用场景的示例。
21 2
|
14天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
41 3
|
14天前
|
Java 测试技术 API
Spring Boot 单元测试 0基础教程
Spring Boot 单元测试 0基础教程
15 0