本文介绍如何从传统身份验证方法迁移到更安全的无密码连接与 Azure SQL 数据库。
必须对 Azure SQL 数据库的应用程序请求进行身份验证。 Azure SQL 数据库为应用提供多种不同的安全连接方式。 其中一种方法是使用密码。 但是,应尽可能确定应用程序中的无密码连接优先级。
比较身份验证选项
当应用程序使用 Azure SQL 数据库进行身份验证时,它提供用于连接到数据库的用户名和密码对。 根据标识的存储位置,有两种类型的身份验证:Microsoft Entra 身份验证和 Azure SQL 数据库身份验证。
Microsoft Entra 身份验证
Microsoft Entra 身份验证是使用 Microsoft Entra ID 中定义的标识连接到 Azure SQL 数据库的一种机制。 通过使用Microsoft Entra身份验证,可以在中心位置管理数据库用户标识和其他Microsoft 服务,从而简化权限管理。
使用 Microsoft Entra ID 进行身份验证可提供以下优势:
- 以统一的方式在 Azure 服务中对用户进行身份验证。
- 在单个位置管理密码策略和密码轮换。
- Microsoft Entra ID 支持的多种形式的身份验证,因此无需存储密码。
- 客户可以使用外部(Microsoft Entra ID)组管理数据库权限。
- Microsoft Entra 身份验证使用 Azure SQL 数据库用户在数据库级别对身份进行验证。
- 对连接到 Azure SQL 数据库的应用程序支持基于令牌的身份验证。
Azure SQL 数据库身份验证
可以在 Azure SQL 数据库中创建帐户。 如果选择使用密码作为帐户的凭据,表 sys.database_principals 将存储这些凭据。 由于Azure SQL 数据库存储这些密码,因此需要自行管理密码的轮换。
虽然可以使用密码连接到Azure SQL 数据库,但请谨慎使用它们。 勤奋地不要在不安全的位置公开密码。 获得密码访问权限的任何人都可以进行身份验证。 例如,如果你不小心将连接字符串签入源代码管理中,通过不安全的电子邮件发送它,把它粘贴到错误的聊天窗口中,或者让无权查看它的人看到了它,恶意用户就可能访问该应用程序。 相反,请考虑将应用程序更新为使用无密码连接。
引入无密码连接
使用无密码连接,无需在应用程序代码、配置文件或环境变量中存储任何凭据即可连接到 Azure 服务。
许多 Azure 服务支持无密码连接,例如通过 Azure 托管标识。 这些技术提供可靠的安全功能,可以使用 Azure 标识客户端库中的 DefaultAzureCredential 实现。 本教程介绍如何更新现有应用程序以使用 DefaultAzureCredential ,而不是连接字符串等替代项。
DefaultAzureCredential 支持多种身份验证方法,并自动确定应在运行时使用哪些方法。 此方法使应用能够在不同环境(本地开发与生产环境)中使用不同的身份验证方法,而无需实现特定于环境的代码。
DefaultAzureCredential 查找凭据的顺序和位置可在 Azure Identity 库概述 中找到。 例如,在本地工作时, DefaultAzureCredential 通常会使用开发人员用于登录 Visual Studio 的帐户进行身份验证。 将应用部署到 Azure 后, DefaultAzureCredential 将自动切换到使用 托管标识。 此转换不需要更改代码。
若要确保连接无密码,必须同时考虑本地开发和生产环境。 如果任一位置都需要连接字符串,则应用程序不会无密码。
在本地开发环境中,可以使用适用于 Visual Studio Code 或 IntelliJ 的 Azure CLI、Azure PowerShell、Visual Studio 或 Azure 插件进行身份验证。 在这种情况下,可以在应用程序中使用该凭据,而不是配置属性。
将应用程序部署到 Azure 托管环境(例如虚拟机)时,可以在该环境中分配托管标识。 然后,无需提供凭据即可连接到 Azure 服务。
注释
托管标识为应用或服务提供一个安全身份。 标识由 Azure 平台管理,不需要预配或轮换任何机密。 可以在 概述 文档中阅读有关托管标识的详细信息。
注释
由于用于Azure SQL 数据库的 JDBC 驱动程序尚不支持来自本地环境的无密码连接,本文仅重点介绍部署到Azure托管环境的应用程序,以及如何将其迁移到使用无密码连接。
迁移现有应用程序以使用无密码连接
以下步骤说明如何迁移现有应用程序以使用无密码连接,而不是基于密码的解决方案。
0) 准备工作环境
首先,使用以下命令设置一些环境变量。
export AZ_RESOURCE_GROUP=<YOUR_RESOURCE_GROUP>
export AZ_DATABASE_SERVER_NAME=<YOUR_DATABASE_SERVER_NAME>
export AZ_DATABASE_NAME=demo
export CURRENT_USERNAME=$(az ad signed-in-user show --query userPrincipalName --output tsv)
export CURRENT_USER_OBJECTID=$(az ad signed-in-user show --query id --output tsv)
将占位符替换为本文中使用的以下值:
-
<YOUR_RESOURCE_GROUP>:你的资源所在的资源组名称。 -
<YOUR_DATABASE_SERVER_NAME>:Azure SQL 数据库服务器的名称。 它应该在整个 Azure 中是唯一的。
1) 配置 Azure SQL 数据库
1.1) 启用基于 Microsoft Entra ID 的身份验证
若要将Microsoft Entra ID访问权限用于Azure SQL 数据库,请先设置Microsoft Entra管理员用户。 只有Microsoft Entra管理员用户可以创建或启用基于Microsoft Entra ID身份验证的用户。
如果使用Azure CLI,请运行以下命令以确保它具有足够的权限:
az login --scope https://graph.microsoft.com/.default
然后运行以下命令来设置Microsoft Entra管理员:
az sql server ad-admin create \
--resource-group $AZ_RESOURCE_GROUP \
--server $AZ_DATABASE_SERVER_NAME \
--display-name $CURRENT_USERNAME \
--object-id $CURRENT_USER_OBJECTID
此命令将Microsoft Entra管理员设置为当前登录用户。
注释
每个 Azure SQL 数据库服务器只能创建一个Microsoft Entra 管理员。 选择另一位管理员会替换服务器上已配置的现有 Microsoft Entra 管理员。
2) 迁移应用代码以使用无密码连接
接下来,使用以下步骤更新代码以使用无密码连接。 虽然从概念上讲相似,但每种语言使用不同的实现详细信息。
在你的项目中,添加对
azure-identity包的以下引用。 此库包含实现无密码连接所需的所有实体。<dependency> <groupId>com.azure</groupId> <artifactId>azure-identity</artifactId> <version>1.5.4</version> </dependency>在 JDBC URL.v 中启用 Microsoft Entra 托管标识身份验证。确定代码中当前创建
java.sql.Connection以连接到 Azure SQL 数据库的位置。 更新代码以匹配以下示例:String url = "jdbc:sqlserver://$AZ_DATABASE_SERVER_NAME.database.windows.net:1433;databaseName=$AZ_DATABASE_NAME;authentication=ActiveDirectoryMSI;" Connection con = DriverManager.getConnection(url);将两
$AZ_DATABASE_SERVER_NAME个变量和一个$AZ_DATABASE_NAME变量替换为本文开头配置的值。从 JDBC URL 中删除
user和password。
3) 配置 Azure 托管环境
将应用程序配置为使用无密码连接后,将应用程序部署到Azure后,相同的代码可以向Azure服务进行身份验证。 例如,部署到已分配托管标识的 Azure 应用服务实例的应用程序可以连接到 Azure 存储。
在本部分中,将执行两个步骤,使应用程序能够以无密码方式在Azure托管环境中运行:
- 为 Azure 托管环境分配托管标识。
- 为托管标识分配角色。
注释
Azure 还提供 服务连接器,可帮助将托管服务与 SQL Server 连接。 通过使用服务连接器配置托管环境,可以省略将角色分配给托管标识的步骤,因为 Service Connector 会为你执行该操作。 以下部分介绍如何通过两种方式配置 Azure 托管环境:一种是通过服务连接器,另一种是通过直接配置每个托管环境。
重要
服务连接器的命令需要 Azure CLI 2.41.0 或更高版本。
使用 Azure 门户分配托管标识
以下步骤演示如何为各种 Web 托管服务分配系统分配的托管标识。 托管标识可以使用之前设置的应用配置安全地连接到其他Azure服务。
在 Azure 应用服务实例的主概述页上,从导航窗格中选择 “标识 ”。
在 “系统分配 ”选项卡上,确保将 “状态 ”字段设置为 “打开”。 系统分配的标识由 Azure 内部管理,并为你处理管理任务。 标识的详细信息和 ID 永远不会在代码中公开。
还可以使用 Azure CLI 在 Azure 托管环境中分配托管标识。
可以使用 az webapp identity assign 命令将托管标识分配给 Azure 应用服务实例,如以下示例所示:
export AZ_MI_OBJECT_ID=$(az webapp identity assign \
--resource-group $AZ_RESOURCE_GROUP \
--name <service-instance-name> \
--query principalId \
--output tsv)
将角色分配给托管标识
接下来,向创建的托管标识授予访问 SQL 数据库的权限。
- 服务连接器
- Azure CLI
如果使用服务连接器连接了服务,则上一步中的命令已分配了角色,因此可以跳过此步骤。
测试应用程序
进行这些代码更改后,可以生成并重新部署应用程序。 然后,在浏览器中浏览到托管的应用程序。 应用应能够成功连接到 Azure SQL 数据库。 角色分配可能需要几分钟才能通过Azure环境传播。 应用程序现在配置为在本地和生产环境中运行,而开发人员无需管理应用程序本身中的机密。
后续步骤
本教程介绍了如何将应用程序迁移到无密码连接。
若要更深入地了解本文中讨论的概念,请参阅以下资源: