教程:代表已登录用户将应用服务应用连接到 SQL 数据库
本教程介绍如何使用 Microsoft Entra 身份验证提供程序在应用服务应用中启用内置身份验证,然后通过模拟登录用户(也称为代表流),将其连接到后端 Azure SQL 数据库进行扩展。 这是教程:使用托管标识访问数据的更高级连接方法,在企业方案中具有以下优势:
- 消除与后端服务的连接机密,就像托管标识方法一样。
- 使后端数据库(或任何其他 Azure 服务)能够更好地控制谁或多少人可以访问其数据和功能。
- 允许应用向已登录用户定制其数据呈现。
在本教程中,你需要将 Microsoft Entra 身份验证添加到在以下教程之一中部署的示例 Web 应用:
完成后,示例应用将代表已登录用户对安全连接到 SQL 数据库的用户进行身份验证。
注意
本教程所述的步骤支持以下版本:
- .NET Framework 4.8 和更高版本
- .NET 6.0 和更高版本
要学习的知识:
- 为 Azure SQL 数据库启用内置身份验证
- 在 Azure SQL 数据库中禁用其他身份验证选项
- 启用应用服务身份验证
- 使用 Microsoft Entra ID 作为标识提供者
- 代表已登录的 Microsoft Entra 用户访问 Azure SQL 数据库
注意
在本地 Active Directory 域服务 (AD DS) 中,Microsoft Entra 身份验证不同于集成式 Windows 身份验证。 AD DS 和 Microsoft Entra ID 使用的身份验证协议完全不相同。 有关详细信息,请参阅 Microsoft Entra 域服务文档。
如果没有 Azure 订阅,可在开始前创建一个试用帐户。
先决条件
本文是以下任一教程的后续内容:
请先完成这两篇教程之一(如果尚未完成)。 也可调整这些步骤,使用 SQL 数据库来生成自己的 .NET 应用。
为 Azure CLI 准备环境。
1.为数据库服务器配置 Microsoft Entra 身份验证
首先,通过将 Microsoft Entra 用户指定为服务器的管理员,对 SQL 数据库启用 Microsoft Entra 身份验证。 此用户与用于注册 Azure 订阅的 Microsoft 帐户不同。 它必须是你在 Microsoft Entra ID 中创建、导入、同步或邀请到其中的用户。 有关允许的 Microsoft Entra 用户的详细信息,请参阅 SQL 数据库中的 Microsoft Entra 功能和限制。
如果 Microsoft Entra 租户还没有用户,请按照使用 Microsoft Entra ID 添加或删除用户中的步骤创建一个用户。
使用
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
。使用
az sql server ad-admin create
命令,将此 Microsoft Entra 用户添加为 Active Directory 管理员。 在以下命令中,将 <server-name> 替换为服务器名称(不带.database.chinacloudapi.cn
后缀)。az sql server ad-admin create --resource-group <group-name> --server-name <server-name> --display-name ADMIN --object-id $azureaduser
将数据库服务器身份验证限制为 Active Directory 身份验证。 此步骤可有效地禁用 SQL 身份验证。
az sql server ad-only-auth enable --resource-group <group-name> --name <server-name>
有关添加 Active Directory 管理员的详细信息,请参阅预配 Microsoft Entra 管理员(SQL 数据库)。
2. 为应用启用用户身份验证
可通过作为标识提供者的 Microsoft Entra ID 进行身份验证。 有关详细信息,请参阅为应用程序服务应用程序配置 Microsoft Entra 身份验证。
在 Azure 门户菜单上,选择“资源组”,或在任意页面中搜索并选择“资源组”。
在“资源组”中,查找并选择资源组,然后选择应用。
在应用的左侧菜单中,选择“身份验证”,然后选择“添加标识提供者”。
在“添加标识提供者”页上,选择“Microsoft”作为“标识提供者”以登录 Microsoft 和 Microsoft Entra 标识。
接受默认设置,然后选择“添加”。
提示
如果在遇到错误后重新配置应用的身份验证设置,则可能无法通过新的设置在令牌存储中重新生成令牌。 若要确保重新生成令牌,需在注销后重新登录应用。 若要这样做,一个简单的方法是在专用模式下使用浏览器,在应用中更改设置后关闭该浏览器,然后再在专用模式下将其重新打开。
3. 配置对 SQL 数据库的用户模拟
目前,Azure 应用连接到 SQL 数据库并使用 SQL 身份验证(用户名和密码),该身份验证作为应用设置进行管理。 在此步骤中,向应用授予代表已登录的 Microsoft Entra 用户访问 SQL 数据库的权限。
在应用的“身份验证”页中,在“标识提供者”下选择应用名称。 此应用注册是自动为你生成的。 在左侧菜单中选择“API 权限”。
选择“添加权限”,然后选择“我的组织使用的 API”。
在搜索框中键入“Azure SQL 数据库”,然后选择结果。
在 Azure SQL 数据库的“请求 API 权限”页中,选择“委托的权限”和“user_impersonation”,然后选择“添加权限”。
4. 配置应用服务,使之返回可用的访问令牌
Microsoft Entra ID 中的应用注册现在具有通过模拟已登录用户连接到 SQL 数据库所需的权限。 接下来,配置应用服务应用以提供可用的访问令牌。
在 PowerShell 中的应用上运行以下命令,以将 scope
参数添加到身份验证设置 identityProviders.azureActiveDirectory.login.loginParameters
。
authSettings=$(az webapp auth show --resource-group <group-name> --name <app-name>)
authSettings=$(echo "$authSettings" | jq '.properties' | jq '.identityProviders.azureActiveDirectory.login += {"loginParameters":["scope=openid profile email offline_access https://database.chinacloudapi.cn/user_impersonation"]}')
az webapp auth set --resource-group <group-name> --name <app-name> --body "$authSettings"
这些命令有效地添加了具有额外自定义范围的 loginParameters
属性。 下面解释了请求的范围:
- 默认情况下,应用服务已请求
openid
、profile
和email
。 有关信息,请参阅 OpenID Connect 范围。 https://database.chinacloudapi.cn/user_impersonation
指的是 Azure SQL 数据库。 它是提供 JWT 令牌的范围,该令牌包含 SQL 数据库作为令牌受众。- 为方便起见,此处包含了 offline_access(便于刷新令牌)。
现在已配置好了应用。 应用现在可以生成 SQL 数据库接受的令牌。
5. 在应用程序代码中使用访问令牌
为项目执行的步骤取决于你是使用实体框架(适用于 ASP.NET 的默认选项)还是使用 Entity Framework Core(适用于 ASP.NET Core 的默认选项)。
在 Visual Studio 中,打开包管理器控制台并更新实体框架:
Update-Package EntityFramework
在 Models/MyDbContext.cs 中的 DbContext 对象内,将以下代码添加到默认构造函数。
var conn = (System.Data.SqlClient.SqlConnection)Database.Connection; conn.AccessToken = System.Web.HttpContext.Current.Request.Headers["X-MS-TOKEN-AAD-ACCESS-TOKEN"];
6. 发布更改
如果你已学完教程:使用 SQL 数据库在 Azure 中生成 ASP.NET 应用,请使用 SQL 身份验证(用户名和密码)在应用服务中设置连接字符串。 使用以下命令删除连接机密,但将 <group-name>、<app-name>、<db-server-name> 和 <db-name> 替换为你自己的内容。
az webapp config connection-string set --resource-group <group-name> --name <app-name> --connection-string-type SQLAzure --settings MyDbConnection="server=tcp:<db-server-name>.database.chinacloudapi.cn;database=<db-name>;"
在 Visual Studio 中发布更改。 在“解决方案资源管理器”中,右键单击 “DotNetAppSqlDb”项目,然后选择“发布”。
在发布页中选择“发布”。
当新网页显示待办事项列表时,应用将代表已登录的 Microsoft Entra 用户连接到数据库。
现在应该可以像以前一样编辑待办事项列表了。
7.清理资源
在前面的步骤中,你在资源组中创建了 Azure 资源。 如果你认为将来不再需要这些资源,请运行以下命令删除资源组:
az group delete --name <group-name>
此命令可能需要花费一点时间运行。
常见问题
- 为什么出现
Login failed for user '<token-identified principal>'.
错误? - 如何在 Azure SQL 数据库中添加其他 Microsoft Entra 用户或组?
- 使用应用服务身份验证时,如何在本地调试?
- 访问令牌过期时会发生什么情况?
为什么出现 Login failed for user '<token-identified principal>'.
错误?
导致此错误的最常见原因是:
- 你在本地运行代码,
X-MS-TOKEN-AAD-ACCESS-TOKEN
请求标头中没有有效的令牌。 请参阅使用应用服务身份验证时,如何在本地调试?。 - SQL 数据库未配置 Microsoft Entra 身份验证。
- 不允许已登录用户连接到数据库。 请参阅如何在 Azure SQL 数据库中添加其他 Microsoft Entra 用户或组?。
如何在 Azure SQL 数据库中添加其他 Microsoft Entra 用户或组?
SQL 数据库文档中的创建映射到 Microsoft Entra 标识的包含用户。
以下 Transact-SQL 示例将 Microsoft Entra 标识添加到 SQL Server,并为其提供一些数据库角色:
CREATE USER [<user-or-group-name>] FROM EXTERNAL PROVIDER; ALTER ROLE db_datareader ADD MEMBER [<user-or-group-name>]; ALTER ROLE db_datawriter ADD MEMBER [<user-or-group-name>]; ALTER ROLE db_ddladmin ADD MEMBER [<user-or-group-name>]; GO
使用应用服务身份验证时,如何在本地调试?
由于应用服身份验证是 Azure 中的一项功能,因此无法在本地环境中使用相同的代码。 与 Azure 中运行的应用不同,本地代码不会从应用服的身份验证中间件中获益。 你有几个选择:
- 使用
Active Directory Interactive
从本地环境连接到 SQL 数据库。 身份验证流不会将用户登录到应用本身,但它确实使用已登录用户连接到后端数据库,并允许在本地测试数据库授权。 - 将访问令牌
https://<app-name>.chinacloudsites.cn/.auth/me
手动复制到代码中,以取代X-MS-TOKEN-AAD-ACCESS-TOKEN
请求标头。 - 如果从 Visual Studio 进行部署,请使用应用服务应用远程调试。
访问令牌过期时会发生什么情况?
访问令牌在一段时间后会过期。
后续步骤
你已了解:
- 为 Azure SQL 数据库启用内置身份验证
- 在 Azure SQL 数据库中禁用其他身份验证选项
- 启用应用服务身份验证
- 使用 Microsoft Entra ID 作为标识提供者
- 代表已登录的 Microsoft Entra 用户访问 Azure SQL 数据库