你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

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

应用服务在 Azure 中提供高度可缩放、自修补的 Web 托管服务。 它还为应用提供托管标识,这是一项统包解决方案,可以确保安全地访问 Azure SQL 数据库和其他 Azure 服务。 应用服务中的托管标识可以让应用更安全,因为不需在应用中存储机密,例如连接字符串中的凭据。 在本教程中,你要将托管标识添加到在以下教程之一中生成的示例 Web 应用:

完成后,示例应用就可以安全地连接到 SQL 数据库,不需用户名和密码。

Architecture diagram for tutorial scenario.

注意

本教程所述的步骤支持以下版本:

  • .NET Framework 4.8 及更高版本
  • .NET 6.0 及更高版本

有关其他语言框架 (Node.js、Python 和 Java) 中的 Azure Database for MySQL 或 Azure Database for PostgreSQL 指南,请参阅教程:使用托管标识从应用服务连接到 Azure 数据库,而无需使用密钥

要学习的知识:

  • 启用托管标识
  • 授予 SQL 数据库访问托管标识的权限
  • 配置实体框架以将 Microsoft Entra 身份验证与 SQL 数据库配合使用
  • 使用 Microsoft Entra 身份验证从 Visual Studio 连接到 SQL 数据库

注意

在本地 Active Directory 域服务 (AD DS) 中,Microsoft Entra 身份验证不同于集成式 Windows 身份验证。 AD DS 和 Microsoft Entra ID 使用的身份验证协议完全不相同。 有关详细信息,请参阅 Microsoft Entra 域服务文档

如果没有 Azure 订阅,请在开始之前创建一个 Azure 免费帐户

先决条件

本文是以下任一教程的后续内容:

请先完成这两篇教程之一(如果尚未完成)。 也可调整这些步骤,使用 SQL 数据库来生成自己的 .NET 应用。

若要使用 SQL 数据库作为后端调试应用程序,请确保已经允许从计算机连接客户端。 否则,请遵循使用 Azure 门户管理服务器级 IP 防火墙规则中的步骤添加客户端 IP。

为 Azure CLI 准备环境。

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

首先,通过将 Microsoft Entra 用户指定为服务器的管理员,对 SQL 数据库启用 Microsoft Entra 身份验证。 此用户与用于注册 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)
    

    提示

    若要查看 Microsoft Entra ID 中所有用户主体名称的列表,请运行 az ad user list --query '[].userPrincipalName'

  3. 使用 Cloud Shell 中的 az sql server ad-admin create 命令,将此 Microsoft Entra 用户添加为 Active Directory 管理员。 在以下命令中,将 <server-name> 替换为服务器名称(不带 .database.windows.net 后缀)。

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

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

2. 设置开发环境

  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 身份验证来开发和调试应用程序。

3. 修改项目

注意

Microsoft.Azure.Services.AppAuthentication 不再被推荐用于新的 Azure SDK。 已将其替换为新的 Azure 标识客户端库(可用于 .NET、Java、TypeScript 和 Python),应将此库用于所有新的开发。 有关如何迁移到 Azure Identity 的信息,请参阅:AppAuthentication 到 Azure.Identity 的迁移指南

为项目执行的步骤取决于你是使用 Entity Framework Core(适用于 ASP.NET Core 的默认选项)还是使用 Entity Framework(适用于 ASP.NET 的默认选项)。

  1. 在 Visual Studio 中,打开包管理器控制台,并添加 NuGet 包 Microsoft.Data.SqlClient

    Install-Package Microsoft.Data.SqlClient -Version 5.1.0
    
  2. ASP.NET Core 和 SQL 数据库教程中,appsettings.json 中的 MyDbConnection 连接字符串尚未使用。 本地环境和 Azure 环境都从各自的环境变量获取连接字符串,这样,连接机密就无需保留在源文件内。 但现在使用 Active Directory 身份验证,不再有机密了。 在 appsettings.json 中,请将 MyDbConnection 连接字符串的值替换为:

    "Server=tcp:<server-name>.database.windows.net;Authentication=Active Directory Default; Database=<database-name>;"
    

    注意

    Active Directory 默认身份验证类型可用于本地计算机和 Azure 应用服务。 驱动程序尝试使用各种方式从 Microsoft Entra ID 获取令牌。 如果应用已部署,它将从应用的托管标识获取令牌。 如果应用在本地运行,它会尝试从 Visual Studio、Visual Studio Code 和 Azure CLI 获取令牌。

    这就是连接到 SQL 数据库所要完成的所有准备工作。 在 Visual Studio 中调试时,代码使用在 2 中配置的 Microsoft Entra 用户。设置开发环境。 稍后你将设置 SQL 数据库,以允许“应用服务”应用的托管标识建立连接。 DefaultAzureCredential 类将令牌缓存在内存中,在过期前才将其从 Microsoft Entra ID 检索出来。 不需要任何自定义代码就可以刷新该令牌。

  3. 键入 Ctrl+F5,再次运行该应用。 浏览器中相同的 CRUD 应用程序现使用 Microsoft Entra 身份验证直接连接到 Azure SQL 数据库。 此设置使你能够从 Visual Studio 运行数据库迁移。

4. 使用托管标识连接性

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

注意

虽然本部分的说明适用于系统分配的标识,但用户分配的标识同样可以很容易地使用。 为此, 需更改 az webapp identity assign command,以便分配所需的用户分配标识。 然后,在创建 SQL 用户时,请确保使用用户分配的标识资源的名称,而不是站点名称。

在应用上启用托管标识

若要为 Azure 应用启用托管标识,请在 Cloud Shell 中使用 az webapp identity assign 命令。 在以下命令中,替换 <app-name>

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

注意

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

这是一个输出示例:

{
  "additionalProperties": {},
  "principalId": "21dfa71c-9e6f-4d17-9e90-1d28801c9735",
  "tenantId": "72f988bf-86f1-41af-91ab-2d7cd011db47",
  "type": "SystemAssigned"
}

向托管标识授予权限

注意

如果需要,可将该标识添加到 Microsoft Entra 组,然后将 SQL 数据库访问权限授予 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 myResourceGroup --name <app-name> --query principalId --output tsv)
az ad group member add --group $groupid --member-id $msiobjectid
az ad group member list -g $groupid
  1. 在 Cloud Shell 中,使用 SQLCMD 命令登录到 SQL 数据库。 将 <server-name> 替换为服务器名称,<db-name> 替换为应用使用的数据库名称,<aad-user-name><aad-password> 替换为 Microsoft Entra 用户的凭据。

    sqlcmd -S <server-name>.database.windows.net -d <db-name> -U <aad-user-name> -P "<aad-password>" -G -l 30
    
  2. 在所需数据库的 SQL 提示符下运行以下命令,以授予应用所需的最小权限。 例如,

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

    <identity-name> 是 Microsoft Entra ID 中的托管标识的名称。 如果标识是系统分配的,则此名称始终与应用服务应用的名称相同。 对于部署槽位,其系统分配的标识的名称为 <app-name>/slots/<slot-name>。 若要为 Microsoft Entra 组授予权限,请改为使用组的显示名称(例如,myAzureSQLDBAccessGroup)。

  3. 键入 EXIT,返回到 Cloud Shell 提示符窗口。

    注意

    托管标识的后端服务还保留一个令牌缓存,只有在过期的情况下才更新目标资源的令牌。 如果在配置 SQL 数据库权限时出错,并尝试在使用应用获取令牌后修改权限,则在缓存的令牌过期之前,实际上不会获得具有更新权限的新令牌。

    注意

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

修改连接字符串

请记住,在 Web.configappsettings.json 中所做的相同更改适用于托管标识,因此只需删除应用服务中的现有连接字符串,该字符串由 Visual Studio 在首次部署应用时创建。 使用以下命令,但将 <app-name> 替换为应用名称。

az webapp config connection-string delete --resource-group myResourceGroup --name <app-name> --setting-names MyDbConnection

5. 发布更改

现在,剩下的操作是将更改发布到 Azure。

  1. 如果你是在学完教程:使用 SQL 数据库在 Azure 中生成 ASP.NET 应用 后转到本教程,请在 Visual Studio 中发布更改。 在“解决方案资源管理器”中,右键单击 “DotNetAppSqlDb”项目,然后选择“发布”。

    Publish from Solution Explorer

  2. 在发布页中选择“发布”。

    重要

    确保应用服务的名称与任何现有的应用注册都不匹配。 这会导致主体 ID 冲突。

当新网页显示待办事项列表时,表明应用使用了托管标识连接到数据库。

Azure app after Code First Migration

现在应该可以像以前一样编辑待办事项列表了。

清理资源

在前面的步骤中,你在资源组中创建了 Azure 资源。 如果认为将来不需要这些资源,请在 Cloud Shell 中运行以下命令删除资源组:

az group delete --name myResourceGroup

此命令可能需要花费一点时间运行。

后续步骤

你已了解:

  • 启用托管标识
  • 授予 SQL 数据库访问托管标识的权限
  • 配置实体框架以将 Microsoft Entra 身份验证与 SQL 数据库配合使用
  • 使用 Microsoft Entra 身份验证从 Visual Studio 连接到 SQL 数据库