教程:使用托管标识从应用服务连接到 Azure 数据库,而无需使用密钥

应用服务在 Azure 中提供高度可缩放、自修补的 Web 托管服务。 它还为应用提供托管标识,这是一项统包解决方案,可以确保安全地访问 Azure SQL 数据库,包括:

注意

本教程不包括 Azure Cosmos DB 指南,该指南支持以不同的方式进行 AMicrosoft Entra 身份验证。 有关详细信息,请参阅 Azure Cosmos DB 文档,例如使用系统分配的托管标识访问 Azure Cosmos DB 数据

应用服务中的托管标识可以让应用更安全,因为不需在应用中存储机密,例如连接字符串中的凭据。 本教程介绍如何使用托管标识从应用服务连接到上述数据库。

要学习的知识:

  • 将 Microsoft Entra 用户配置为 Azure 数据库的管理员。
  • 以 Microsoft Entra 用户身份连接数据库。
  • 为应用服务应用配置系统分配或用户分配的托管标识。
  • 授予数据库访问托管标识的权限。
  • 使用托管标识从代码 (.NET Framework 4.8、.NET 6、Node.js、Python、Java) 连接到 Azure 数据库。
  • 以 Microsoft Entra 用户身份从开发环境连接到 Azure 数据库。

如果没有 Azure 订阅,可在开始前创建一个试用帐户

先决条件

  • 基于 .NET、Node.js、Python 或 Java 在应用服务中创建应用。
  • 使用 Azure SQL 数据库、Azure Database for MySQL 或 Azure Database for PostgreSQL 创建数据库服务器。
  • 应熟悉标准连接模式(使用用户名和密码),并且能够成功从应用服务应用连接到所选的数据库。

为 Azure CLI 准备环境。

可以使用本地 Azure CLI。

  • 如果需要,请安装 Azure CLI 来运行 CLI 参考命令。

  • 本地 Azure CLI,请了解如何安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI

    • 通过使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录

    • 出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展详细信息,请参阅使用 Azure CLI 的扩展

    • 运行 az version 以查找安装的版本和依赖库。 若要升级到最新版本,请运行 az upgrade

1.向数据库授予对 Microsoft Entra 用户的访问权限

首先,通过将 Microsoft Entra 用户指定为服务器的管理员,对 Azure 数据库启用 Microsoft Entra 身份验证。 对于本教程中的方案,你将使用此用户从本地开发环境连接到 Azure 数据库。 稍后,为应用服务应用设置托管标识,以便从 Azure 中进行连接。

注意

此用户与用于注册 Azure 订阅的 Microsoft 帐户不同。 它必须是你在 Microsoft Entra ID 中创建、导入、同步或邀请到其中的用户。 有关允许的 Microsoft Entra 用户的详细信息,请参阅 SQL 数据库中的 Microsoft Entra 功能和限制

  1. 如果 Microsoft Entra 租户还没有用户,请按照使用 Microsoft Entra ID 添加或删除用户中的步骤创建一个用户。

  2. 使用 az ad user list 查找 Microsoft Entra 用户的对象 ID,并替换 <user-principal-name>。 结果会保存到变量中。

    azureaduser=$(az ad user list --filter "userPrincipalName eq '<user-principal-name>'" --query [].id --output tsv)
    
  1. 使用 Azure CLI 中的 az sql server ad-admin create 命令,将此 Microsoft Entra 用户添加为 Active Directory 管理员。 在以下命令中,将<组名称><服务器名称>替换为你自己的参数。

    az sql server ad-admin create --resource-group <group-name> --server-name <server-name> --display-name ADMIN --object-id $azureaduser
    

    有关添加 Active Directory 管理员的详细信息,请参阅为服务器预配 Microsoft Entra 管理员

2、为应用配置托管标识

接下来,配置应用服务应用,使用托管标识连接到 SQL 数据库。

  1. 在 Azure CLI 中使用 az webapp identity assign 命令,为应用服务应用启用托管标识。 在以下命令中,替换 <app-name>

    az webapp identity assign --resource-group <group-name> --name <app-name>
    

    注意

    若要为部署槽位启用托管标识,请添加 --slot <slot-name>,并在 <slot-name> 中使用槽名称。

  2. 需要向标识授予访问数据库的权限。 在 Azure CLI 中,使用以下命令登录到数据库。 从1、向 Azure AD 用户授予访问数据库的权限,将 <server-name> 替换为服务器名称,将 <database-name> 替换为应用使用的数据库名称,将 <aad-user-name><aad-password> 替换为 Azure AD 用户的凭据。

    sqlcmd -S <server-name>.database.chinacloudapi.cn -d <database-name> -U <aad-user-name> -P "<aad-password>" -G -l 30
    
  3. 运行以下数据库命令以授予应用所需的权限。 例如,

    CREATE USER [<app-name>] FROM EXTERNAL PROVIDER;
    ALTER ROLE db_datareader ADD MEMBER [<app-name>];
    ALTER ROLE db_datawriter ADD MEMBER [<app-name>];
    ALTER ROLE db_ddladmin ADD MEMBER [<app-name>];
    GO
    

    对于部署槽,请使用 <app-name>/slots/<slot-name> 而不是 <app-name>

3、修改代码

  1. 安装依赖项。

    dotnet add package Microsoft.Data.SqlClient
    
  2. 从服务连接器添加的环境变量中获取 Azure SQL 数据库连接字符串。

    using Microsoft.Data.SqlClient;
    
    // AZURE_SQL_CONNECTIONSTRING should be one of the following:
    // For system-assigned managed identity:"Server=tcp:<server-name>.database.chinacloudapi.cn;Database=<database-name>;Authentication=Active Directory Default;TrustServerCertificate=True"
    // For user-assigned managed identity: "Server=tcp:<server-name>.database.chinacloudapi.cn;Database=<database-name>;Authentication=Active Directory Default;User Id=<client-id-of-user-assigned-identity>;TrustServerCertificate=True"
    
    string connectionString = 
        Environment.GetEnvironmentVariable("AZURE_SQL_CONNECTIONSTRING")!;
    
    using var connection = new SqlConnection(connectionString);
    connection.Open();
    

    有关详细信息,请参阅使用 Active Directory 托管标识身份验证

4、设置开发环境

此代码示例使用 DefaultAzureCredential 从 Microsoft Entra ID 为 SQL 数据库获取可使用的令牌,然后将其添加到数据库连接。 虽然可以自定义 DefaultAzureCredential,但默认情况下已广泛适用。 它从已登录的 Microsoft Entra 用户或托管标识获取令牌,具体取决于是在开发环境中还是在应用服务本地运行。

无需进一步更改,代码即可在 Azure 中运行。 但是,若要在本地调试代码,开发环境需要已登录 Microsoft Entra 的用户。 在此步骤中,你将以 Microsoft Entra 用户身份登录来配置所选环境。

  1. Visual Studio for Windows 集成了 Microsoft Entra 身份验证。 若要在 Visual Studio 中启用开发和调试,请在 Visual Studio 中添加 Microsoft Entra 用户,方法是从菜单中依次选择“文件”>“帐户设置”,然后选择“登录”“添加”

  2. 若要设置进行 Azure 服务身份验证的 Microsoft Entra 用户,请从菜单中依次选择“工具”>“选项”,然后依次选择“Azure 服务身份验证”>“帐户选择”。 选择已添加的 Microsoft Entra 用户,然后选择“确定”

有关为 Microsoft Entra 身份验证设置开发环境的详细信息,请参阅适用于 .NET 的 Azure 标识客户端库

现已准备好将 SQL 数据库作为后端,使用 Microsoft Entra 身份验证来开发和调试应用程序。

5、测试并发布

  1. 在开发环境中运行代码。 代码使用环境中的已登录 Microsoft Entra 用户连接到后端数据库。 用户可以访问数据库,因为该用户已配置为数据库的 Microsoft Entra 管理员。

  2. 使用首选发布方法将代码发布到 Azure。 在应用服务中,代码使用应用的托管标识连接到后端数据库。

常见问题

托管标识是否支持 SQL Server?

本地 SQL Server 不支持 Microsoft Entra ID 和托管标识。

我收到错误 Login failed for user '<token-identified principal>'.

尝试为其请求令牌的托管标识无权访问 Azure 数据库。

我更改了应用服务身份验证或关联的应用注册。 为什么我仍然获取旧令牌?

托管标识的后端服务还保留一个令牌缓存,只有在过期的情况下才更新目标资源的令牌。 如果在尝试在使用应用获取令牌修改权限,则在缓存的令牌过期之前,实际上不会获得具有更新权限的新令牌。 解决此问题的最佳方式是使用新的 InPrivate (Edge) /private (Safari) /Incognito (Chrome) 窗口测试更改。 这样一来,请务必从新的经过身份验证的会话开始。

如何将托管标识添加到 Microsoft Entra 组?

如果需要,可将该标识添加到 Microsoft Entra 组,然后将访问权限授予 Microsoft Entra 组,而不是授予该标识。 例如,以下命令将上一步中的托管标识添加到名为 myAzureSQLDBAccessGroup 的新组:

groupid=$(az ad group create --display-name myAzureSQLDBAccessGroup --mail-nickname myAzureSQLDBAccessGroup --query objectId --output tsv)
msiobjectid=$(az webapp identity show --resource-group <group-name> --name <app-name> --query principalId --output tsv)
az ad group member add --group $groupid --member-id $msiobjectid
az ad group member list -g $groupid

若要为 Microsoft Entra 组授予数据库权限,请参阅相应数据库类型的文档。

我收到错误 SSL connection is required. Please specify SSL options and retry

连接到 Azure 数据库需要其他设置,并且超出了本教程的范围。 有关详细信息,请参阅下列相应链接:

在 Azure Database for PostgreSQL 中配置 TLS 连接 - 单一服务器在应用程序中配置 SSL 连接,以便安全地连接到 Azure Database for MySQL

后续步骤

你已了解:

  • 将 Microsoft Entra 用户配置为 Azure 数据库的管理员。
  • 以 Microsoft Entra 用户身份连接数据库。
  • 为应用服务应用配置系统分配或用户分配的托管标识。
  • 授予数据库访问托管标识的权限。
  • 使用托管标识从代码 (.NET Framework 4.8、.NET 6、Node.js、Python、Java) 连接到 Azure 数据库。
  • 以 Microsoft Entra 用户身份从开发环境连接到 Azure 数据库。