“用户''登录失败。”使用 EF 代码优先实现通过 MSI 访问 Azure SQL DB 时出现 SqlException

Posted

技术标签:

【中文标题】“用户\'\'登录失败。”使用 EF 代码优先实现通过 MSI 访问 Azure SQL DB 时出现 SqlException【英文标题】:"Login failed for user ''." SqlException when accessing Azure SQL DB via MSI with a EF code-first implementation“用户''登录失败。”使用 EF 代码优先实现通过 MSI 访问 Azure SQL DB 时出现 SqlException 【发布时间】:2019-06-11 02:17:05 【问题描述】:

我正在尝试让 Azure App Service 应用程序利用托管服务标识 (MSI) 并连接到 Azure SQL 数据库,但 .NET Framework 4.7 应用程序在启动时失败并出现以下错误:

System.Data.SqlClient.SqlException: Login failed for user ''.
System.InvalidOperationException: This operation requires a connection to the 'master' database. Unable to create a connection to the 'master' database because the original database connection has been opened and credentials have been removed from the connection string. Supply an unopened connection. ---> System.Data.SqlClient.SqlException: Login failed for user ''.

我添加了 Microsoft.Azure.Services.AppAuthentication 和 Microsoft.IdentityModel.Clients.ActiveDirectory nuget 包。

我已在门户中为应用服务启用了系统分配的身份。

我将一个 Active Directory 用户组设置为 Azure SQL 服务器的 Active Directory 管理员。

我在数据库上执行了 CREATE USER "[user here]" FROM EXTERNAL PROVIDER 命令。我可能忘记添加/修改数据库用户 (MSI) 的角色。但是,如果是这种情况,我不会期望出现这种错误。

应用程序的 DbContext 有两个构造函数,其中一个如下:

    public ApplicationDbContext(SqlConnection sqlConnection) : base(sqlConnection, true)
    
        var isRunningLocal = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"));

        sqlConnection.ConnectionString = ConfigurationManager.ConnectionStrings[nameof(ApplicationDbContext)].ConnectionString;

        if (!isRunningLocal)
        
            sqlConnection.AccessToken = new AzureServiceTokenProvider("RunAs=App").GetAccessTokenAsync("https://database.windows.net/").Result;
        

        Database.SetInitializer<ApplicationDbContext>(null);
        //Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDbContext, Migrations.Configuration>());
    

请注意,有两个 Database.SetInitializer() 调用,一个带有 null 参数,另一个带有 MigrateDatabaseToLatestVersion 参数并被注释掉。应用程序在使用前一个选项时运行。如果我注释掉前者并取消注释后者,则会在应用程序启动时引发异常。

为什么异常描述中包含空 ('') 用户?我怀疑实体框架 (EF) 迁移与数据库上 MSI 的身份验证冲突。我遇到了与我的问题相关的少数几个搜索引擎结果之一,但答案不充分:

https://github.com/MicrosoftDocs/azure-docs/issues/13801 我想继续使用我的团队过去一直使用的数据库迁移。即使数据库已经存在,问题似乎也会出现。

任何帮助将不胜感激。谢谢!

【问题讨论】:

什么对你有帮助? 【参考方案1】:

您能否尝试使用将布尔值作为参数的 MigrateDatabaseToLatestVersion 构造函数,并将其设置为 true?如果没有,它将使用来自使用默认构造函数或注册工厂(如果适用)构造的上下文中的连接信息

根据documentation,如果设置为 true,则初始化程序将使用触发初始化的上下文中的连接信息运行。否则,连接信息将从使用默认构造函数或注册工厂(如果适用)构造的上下文中获取

【讨论】:

瓦伦:感谢您的回复!我尝试了您的建议,但不幸的是,收到了相同的错误消息。然后我重新启动了应用程序服务,不久之后收到一个新错误:System.ArgumentException:参数“connectionString”不能为空、空或仅包含空格。堆栈跟踪中列出了新错误的一些方法(由于注释长度限制而缩短)如下: Check.NotEmpty DbConnectionInfo..ctor DbContextInfo..ctor DbMigrator..ctor MigrateDatabaseToLatestVersion`2.InitializeDatabase 有什么想法吗? 我现在每次访问网站时都会收到相同的“用户登录失败”错误。

以上是关于“用户''登录失败。”使用 EF 代码优先实现通过 MSI 访问 Azure SQL DB 时出现 SqlException的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 3 EF 代码优先 - 掌握详细信息 CRUD

骑士。 EF 代码优先迁移

由EF代码优先决定SQL Azure数据库版本和大小的因素?

C# EF6 代码优先实体状态

EF 代码优先数据库/表初始化 - 何时发生?

EF 代码优先:IValidatable 对象未验证