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

能否本地模拟Azure用户分配托管身份以连接SQL Server开展调试?

可行实现方案(兼容.NET Core 3.1与.NET Framework 4.7.2)

核心思路

利用Azure.Identity库的DefaultAzureCredential类统一身份凭据获取逻辑,配合EF6的连接拦截器动态注入Azure AD访问令牌,本地通过切换身份配置实现和生产托管身份完全一致的权限模拟。

具体实现步骤

  • 步骤1:安装依赖NuGet包
    除已引入的ErikEJ.EntityFramework.SqlServer外,新增安装Azure.Identity包,选择兼容.NET Standard 2.0的版本即可同时适配两个目标框架。
  • 步骤2:实现EF6连接拦截器
    自定义拦截器在连接打开时注入访问令牌,本地调试时走模拟逻辑,生产环境保留原有托管身份连接字符串逻辑:
    using System.Data.Common;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using Azure.Identity;
    using Microsoft.Data.SqlClient;
    using System.Configuration;
    
    // 自定义EF配置类,需和DbContext放在同一程序集
    public class AdDbConfiguration : DbConfiguration
    {
        public AdDbConfiguration()
        {
            SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);
            SetProviderFactory(SqlProviderServices.ProviderInvariantName, SqlClientFactory.Instance);
            AddInterceptor(new AdAuthInterceptor());
        }
    }
    
    public class AdAuthInterceptor : IDbConnectionInterceptor
    {
        // 从配置读取当前要模拟的托管身份客户端ID
        private readonly string _targetMiClientId = ConfigurationManager.AppSettings["TargetManagedIdentityClientId"];
        private readonly DefaultAzureCredential _credential;
    
        public AdAuthInterceptor()
        {
            _credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions
            {
                ManagedIdentityClientId = _targetMiClientId
            });
        }
    
        public void Opened(DbConnection connection, DbConnectionInterceptionContext context)
        {
            var sqlConn = connection as SqlConnection;
            // 判断为本地开发环境时手动注入令牌
            bool isDev = ConfigurationManager.AppSettings["Environment"] == "Development" 
                        || Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development";
            if (sqlConn != null && isDev)
            {
                var token = _credential.GetToken(
                    new Azure.Core.TokenRequestContext(new[] { "https://database.windows.net/.default" }), 
                    default
                );
                sqlConn.AccessToken = token.Token;
            }
        }
    
        // 其余IDbConnectionInterceptor接口方法直接空实现即可
        public void Opening(DbConnection connection, DbConnectionInterceptionContext context) { }
        public void Closed(DbConnection connection, DbConnectionInterceptionContext context) { }
        public void Closing(DbConnection connection, DbConnectionInterceptionContext context) { }
        public void Disposed(DbConnection connection, DbConnectionInterceptionContext context) { }
        public void Disposing(DbConnection connection, DbConnectionInterceptionContext context) { }
        public void BeganTransaction(DbConnection connection, BeginTransactionInterceptionContext context) { }
        public void BeginningTransaction(DbConnection connection, BeginTransactionInterceptionContext context) { }
        public void EnlistedTransaction(DbConnection connection, EnlistTransactionInterceptionContext context) { }
        public void EnlistingTransaction(DbConnection connection, EnlistTransactionInterceptionContext context) { }
    }
    
  • 步骤3:本地多身份调试配置
    要模拟不同托管身份访问不同schema的场景,只需修改配置文件中的TargetManagedIdentityClientId值,同时按以下两种方式之一配置身份凭据:
    • 方式1:本地安装Azure CLI,执行az login登录拥有对应托管身份模拟权限的账号,调试时自动拉取登录账号的凭据获取令牌
    • 方式2:配置对应托管身份的服务主体环境变量:AZURE_CLIENT_ID、AZURE_TENANT_ID、AZURE_CLIENT_SECRET,DefaultAzureCredential会自动读取该配置以目标托管身份的身份获取令牌,权限表现和生产完全一致

注意事项

  • 本地模拟使用的账号/服务主体需要和目标托管身份配置完全一致的SQL角色、schema访问权限,才能1:1复现生产环境的权限表现
  • 生产环境无需修改原有连接字符串和逻辑,仍保留Authentication=Active Directory Managed Identity;User Id=<clientId of managed identity>;配置即可正常运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:54:01