【问题标题】:App Service to EntityFramework using MSI使用 MSI 到 EntityFramework 的应用服务
【发布时间】:2018-04-05 02:38:10
【问题描述】:

我正在尝试将 MSI 改造为现有应用。

原始应用的 DbContext 仅使用了一个构造函数,该构造函数在 web.config 中找到了同名的 ConnectionString。

我已将其修改为使用 DbConnectionFactory 来注入 AccessToken。

public class AppCoreDbContext : DbContext {

    public AppCoreDbContext() : this("AppCoreDbContext")
    {
    }

    public AppCoreDbContext(string connectionStringOrName) : base( OpenDbConnectionBuilder.Create(connectionStringOrName).Result, true)
    {
    }
    ...etc...
}

它正在调用的类如下所示:

public static class OpenDbConnectionBuilder
{
    public static async Task<DbConnection> CreateAsync(string connectionStringName)
    {
        var connectionStringSettings = ConfigurationManager.ConnectionStrings[connectionStringName];

        var dbConnection = DbProviderFactories
            .GetFactory(connectionStringSettings.ProviderName)
            .CreateConnection();
        dbConnection.ConnectionString = connectionStringSettings.ConnectionString;


        await AttachAccessTokenToDbConnection(dbConnection);

        // Think DbContext will open it when first used.
        //await dbConnection.OpenAsync();

        return dbConnection;
    }
    static async Task AttachAccessTokenToDbConnection(IDbConnection dbConnection)
    {
        SqlConnection sqlConnection = dbConnection as SqlConnection;
        if (sqlConnection == null)
        {
            return;
        }
        string msiEndpoint = Environment.GetEnvironmentVariable("MSI_ENDPOINT");
        if (string.IsNullOrEmpty(msiEndpoint))
        {
            return;
        }

        var msiSecret = Environment.GetEnvironmentVariable("MSI_SECRET");
        if (string.IsNullOrEmpty(msiSecret))
        {
            return;
        }

        string accessToken = await AppCoreDbContextMSITokenFactory.GetAzureSqlResourceTokenAsync();
        sqlConnection.AccessToken = accessToken;
    }
}

调用

// Refer to: https://winterdom.com/2017/10/19/azure-sql-auth-with-msi
public static class AppCoreDbContextMSITokenFactory
{
    private const String azureSqlResource = "https://database.windows.net/";

    public static async Task<String> GetAzureSqlResourceTokenAsync()
    {
        var provider = new AzureServiceTokenProvider();
        var result = await provider.GetAccessTokenAsync(azureSqlResource);
        return result;
    }
}

上面的结果是,当用调试器跟踪它时,它到达了

        var result = await provider.GetAccessTokenAsync(azureSqlResource);

然后永远挂起。

注意:我正在使用个人计算机,未加入组织域 - 但我的个人 MSA已被邀请加入组织域。

诚然,我已经中断了几年的开发,而这个问题可能是由于在 await 上犯了一个错误(总是隐含地理解这一点很粗糙)......但是在试图弄清楚这一点时出,并且文档非常稀疏,希望就上述是否是使用 MSI 的预期方法提供反馈。

我想知道:

  • 部署到 Azure 时,我们可以告诉 ARM 来创建 Identity -- 开发时,我们如何告诉本地机器使用 MSI?
  • 如果在开发机器上的连接字符串是到本地数据库的,而我还是创建并添加了令牌,它会忽略它,还是引发异常。
  • 这有点超出了讨论 MSI 的范围,但我以前从未创建过要在 DbContext 中使用的 dbConnection。有谁知道“拥有”连接的 DbContext 的优缺点?我假设在关闭 dbcontext 时拥有并关闭连接会更明智。

基本上...这是全新的,因此非常感谢任何有关使其正常工作的建议 - 能够在没有秘密的情况下进行部署的概念将是真棒并且真的很想获得这个演示工作。

非常感谢!

【问题讨论】:

    标签: azure-managed-identity


    【解决方案1】:

    您好 user9314395:托管服务标识仅适用于在 Azure 上运行的资源。虽然我们不支持本地开发方案,但您可以考虑使用以下(预览版)库:https://docs.microsoft.com/en-us/azure/key-vault/service-to-service-authentication

    【讨论】:

    • 很高兴知道。谢谢。在尝试附加令牌之前,我正在检查环境变量并退出。
    猜你喜欢
    • 1970-01-01
    • 2018-02-28
    • 2011-07-16
    • 1970-01-01
    • 1970-01-01
    • 2012-10-22
    • 2018-03-02
    • 1970-01-01
    • 2018-04-13
    相关资源
    最近更新 更多