Azure 应用服务无法访问 SQL 服务器 - 用户 'NT AUTHORITY\ANONYMOUS LOGON' 登录失败

Azure App Service can't access SQL Server - Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'

我在 Azure 中有一个应用程序服务作为我正在设计的系统的 API。由于 API 负责直接访问数据库,我显然不想尽可能在​​任何地方存储包含凭据的连接字符串,因此我希望使用托管身份来授予应用程序服务对数据库的访问权限(也托管在 Azure 上)。

在 Azure 门户中,我在应用服务的设置部分启用了系统分配的标识,然后通过 SQL 服务器为该服务赋予 SQL 服务器的所有者角色-> 访问控制 -> 角色分配 -> 添加。

据我所知,Active Directory 用户甚至不应该参与其中,因为他们是用户分配的身份而不是系统分配的身份,并且需要进行更多设置(或将其凭据存储在连接字符串中)。

至于代码,它几乎是此代码的副本 >> https://github.com/medhatelmasry/JwtAuthentication,唯一的区别是我添加了

services.BuildServiceProvider().GetService<ApplicationDbContext>().Database.Migrate();

Startup.csConfigureServices 方法的末尾,并按照 Microsoft 的说明将以下内容添加到 ApplicationDbContext 的构造函数中:

var conn = (System.Data.SqlClient.SqlConnection)Database.GetDbConnection();

conn.AccessToken = (new Microsoft.Azure.Services.AppAuthentication.AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;

然而,在 Azure 中尝试 运行 此服务时,我在调用 services.BuildServiceProvider().GetService<ApplicationDbContext>().Database.Migrate();:

时遇到异常

Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'

我试过 Whosebug、MSDN、Azure Help、Pluralsight 以及 Google 出现的任何随机论坛,但都没有找到任何答案。我刚刚度过了整整一个星期,每天熬夜到愚蠢的点,试图修复连接字符串配置,结果发现 Azure 正在更改我给它的连接字符串参数的名称,却只字未提它(在任何 Microsoft 文档中也没有关于它的内容)。

Azure 越来越让我头疼,我什至还没有开始向 API 添加端点,更不用说创建一个实际的应用程序来使用它了,这太荒谬了。

据我了解,您必须完成创建、启用和允许 Azure AD 用户以及将 SQL Admin 设置为 Azure AD 用户的先决条件过程。

这里有一个非常全面的指南,包括为托管身份创建、访问和使用令牌Tutorial: Secure Azure SQL Database connection from App Service using a managed identity

终于在这里找到了答案>> https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-sql#create-a-contained-user-in-the-database-that-represents-the-vms-system-assigned-identity

应用服务确实设置为 服务器 的所有者,但尚未在 数据库 上配置用户,所以我的问题通过 SSMS 和 运行:

登录数据库得到解决

CREATE USER [My App Service Name] FROM EXTERNAL PROVIDER

然后:

ALTER ROLE db_owner ADD MEMBER [My App Service Name]

但是,我在服务器的访问控制 (IAM) 页面上删除了应用服务的所有权角色,并且仍然能够成功连接,不知道为什么会这样,但这可能只是缺少 SQL 我的用户知识。它实际上适合我,因为目前我的应用服务有一个已配置的 SQL 用户,在数据库本身上分配了 db_owner 角色,但没有在整个服务器上分配。