使用 EF Core 托管身份 Sql 身份验证 - 用户“<令牌识别主体>”

问题描述

我有一个 dotnet 5(独立的)Azure Function 应用程序,需要通过 EF Core 5 访问 Azure sql Server 数据库。我想在发出 sql server 请求时使用函数应用程序的托管标识。

我尝试了什么

我按照说明 here

我创建了一个名为“smsrouterdb”的新 AD 帐户并将其设为 Azure sql 管理员。 我的函数应用程序的名称是“func-smsrouter-msdn-01”。因此,在通过 SSMS 以“smsrouterdb”身份登录数据库后,我创建了一个包含的用户,如下所示:

CREATE USER [func-smsrouter-msdn-01] FROM EXTERNAL PROVIDER
ALTER ROLE db_datawriter ADD MEMBER [func-smsrouter-msdn-01]
ALTER ROLE db_datareader ADD MEMBER [func-smsrouter-msdn-01]

然后我通过 http 请求触发了我的函数应用。

发生了什么

我从函数应用程序中收到以下错误

发生了一个或多个错误。 (密钥“身份验证”的值无效。)---> System.ArgumentException:密钥“身份验证”的值无效。在 Microsoft.Data.Common.DbConnectionStringBuilderUtil.ConvertToAuthenticationType(String 关键字,对象值)

我意识到这是因为引用了旧版本的 nuget 包 Microsoft.Data.sqlClient。所以,我明确添加了对 v3.0.0 的引用。

然后我收到以下错误

用户登录失败

但是,如果我将连接字符串的身份验证属性更改为“Active Directory Interactive”并使用以下命令将函数应用的托管标识的对象 ID 提升为 sql Admin:

az sql server ad-admin create --resource-group <tg name> --server-name <server name> --display-name MSIAzureAdmin --object-id "id of managed identity here"

然后正确写入行。我担心的是托管身份不需要是 sql 管理员

配置

包含dbcontext的项目的nuget包是:

"Microsoft.Azure.Services.AppAuthentication" Version="1.6.1"
"Microsoft.EntityFrameworkCore" Version="5.0.6"
"Microsoft.EntityFrameworkCore.Design" Version="5.0.6"
"Microsoft.EntityFrameworkCore.sqlServer" Version="5.0.6"
"WindowsAzure.Storage" Version="9.3.3" />

从主 Azure Function 项目中,我引用了以下 nuget 包:

Microsoft.Data.sqlClient 3.0.0
Serilog.Sinks.MSsqlServer 5.6.0

我的数据库上下文中唯一的代码是:

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            sqlConnection connection = new sqlConnection();
            logger.Loginformation($"sqlSvrConString=[{sharedConfig[ConfigConstants.sqlSvrConnString]}]");
            connection.ConnectionString = sharedConfig[ConfigConstants.sqlSvrConnString];
            optionsBuilder.UsesqlServer(connection);
        }

我的连接字符串是:

Server=servernamehere.database.windows.net;Initial Catalog=dbnamehere;Authentication=Active Directory Managed Identity;

谁能解释为什么这会失败,除非将托管身份设为 sql admin?

解决方法

我认为问题的根本原因是当我发出命令:CREATE USER [function name here] FROM EXTERNAL PROVIDER,虽然函数名拼写正确,但大小写不正确。