You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 4.6.1 EF连接Azure SQL用AD服务主体认证报错求助

.NET Framework 4.6.1 + EF(System.Data.Entity)接入Azure AD服务主体认证解决方案

你的问题核心是:旧版System.Data.SqlClient不支持连接字符串中的Authentication参数,而.NET Framework下的传统EF(基于System.Data.Entity)默认依赖这个旧驱动。以下是具体解决步骤:

1. 替换SQL Client驱动

放弃原生System.Data.SqlClient,改用支持Azure AD认证的Microsoft.Data.SqlClient包:

  • 通过NuGet安装:Install-Package Microsoft.Data.SqlClient(确保版本≥2.0,该版本开始全面支持Azure AD认证参数)

2. 配置EF使用新驱动(针对EF6)

由于传统EF默认绑定System.Data.SqlClient,需要修改配置文件指定新驱动:

修改Web.config/App.config:

  1. 添加DbProviderFactory配置:
<system.data>
  <DbProviderFactories>
    <remove invariant="Microsoft.Data.SqlClient" />
    <add name="Microsoft Data SqlClient" 
         invariant="Microsoft.Data.SqlClient" 
         description=".NET Framework Data Provider for SQL Server" 
         type="Microsoft.Data.SqlClient.SqlClientFactory, Microsoft.Data.SqlClient" />
  </DbProviderFactories>
</system.data>
  1. 更新EF的provider配置:
<entityFramework>
  <providers>
    <provider invariantName="Microsoft.Data.SqlClient" 
              type="Microsoft.Data.SqlClient.SqlProviderServices, Microsoft.Data.SqlClient.EntityFrameworkCore" />
  </providers>
</entityFramework>

3. 两种认证实现方式

方式一:直接使用支持Authentication参数的连接字符串

配置连接字符串如下(此时新驱动可识别Authentication参数):

Data Source=servername.database.windows.net; Encrypt=True; 
Initial Catalog=dbname; Authentication=Active Directory Service Principal; 
User Id=servicePrincipalID; Password=servicePrincipalPassword;

确保DbContext使用该连接字符串初始化即可。

方式二:手动获取AccessToken(更灵活,适合复杂场景)

如果连接字符串方式仍有问题,可通过代码获取服务主体的AccessToken,再绑定到连接对象:

  1. 安装身份认证包:Install-Package Microsoft.IdentityModel.Clients.ActiveDirectory
  2. 实现AccessToken获取方法:
using Microsoft.IdentityModel.Clients.ActiveDirectory;

public string GetAzureSqlAccessToken(string tenantId, string clientId, string clientSecret)
{
    var authContext = new AuthenticationContext($"https://login.microsoftonline.com/{tenantId}");
    var clientCredential = new ClientCredential(clientId, clientSecret);
    var authResult = authContext.AcquireTokenAsync("https://database.windows.net/", clientCredential).Result;
    return authResult.AccessToken;
}
  1. 修改DbContext构造函数,支持传入自定义连接:
using System.Data.Common;
using System.Data.Entity;

public class YourDbContext : DbContext
{
    // 添加接受DbConnection的构造函数
    public YourDbContext(DbConnection connection, bool contextOwnsConnection) 
        : base(connection, contextOwnsConnection)
    {
    }

    // 原有的默认构造函数可保留,用于兼容原有场景
    public YourDbContext() : base("name=YourConnectionString")
    {
    }

    // 定义你的DbSet
    public DbSet<YourEntity> YourEntities { get; set; }
}
  1. 初始化DbContext并使用:
var accessToken = GetAzureSqlAccessToken("你的租户ID", "服务主体ID", "服务主体密钥");
var baseConnStr = "Data Source=servername.database.windows.net; Encrypt=True; Initial Catalog=dbname;";

using (var sqlConn = new Microsoft.Data.SqlClient.SqlConnection(baseConnStr))
{
    sqlConn.AccessToken = accessToken;
    using (var dbContext = new YourDbContext(sqlConn, false)) // false表示DbContext不接管连接生命周期
    {
        // 执行数据库操作,例如:
        var data = dbContext.YourEntities.ToList();
    }
}

关键注意事项

  • 确保服务主体已被授予Azure SQL数据库的访问权限:在Azure SQL中将服务主体添加为数据库用户,并分配对应的角色(如db_owner或自定义权限)
  • 部署到Azure App Service时,可将服务主体的密钥、租户ID等信息存储在App Service的应用设置中,避免硬编码
  • 若使用方式一,需确保Microsoft.Data.SqlClient版本足够新,旧版本可能仍不支持部分Azure AD认证模式

内容的提问来源于stack exchange,提问作者Vigneash Selvaraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 20:15:26