Служба приложений для EntityFramework с использованием MSI
Я пытаюсь переоборудовать MSI в существующее приложение.
DbContext исходного приложения использовал только конструктор, который обнаружил ConnectionString с тем же именем в web.config.
Я изменил его, чтобы использовать 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 был приглашен в домен организации.
По общему признанию, я взял паузу от разработки в течение нескольких лет, и зависание, вероятно, связано с ошибкой в ожидании (всегда грубо понимая это неявно)... но пытаясь понять это, и документация довольно скудная, была бы признательна за обратную связь относительно того, был ли вышеизложенный подход к использованию MSI.
Я задаюсь вопросом:
- При развертывании в Azure мы можем указать ARM создать Identity - при разработке, как мы можем указать локальной машине использовать MSI?
- Если на компьютере разработчика строка подключения находится к локальной базе данных, и я все равно создаю и добавляю токен, будет ли он игнорироваться или возникнет исключение.
- Это немного выходит за рамки обсуждения MSI, но я никогда прежде не создавал dbConnection для использования в DbContext. Кто-нибудь знает плюсы / минусы DbContext, "владеющего" соединением? Я предполагаю, что было бы разумнее иметь и закрыть соединение, когда dbcontext закрыт.
По сути... это все новое, поэтому буду признателен за любые советы, как это работает - концепция возможности развертывания без секретов была бы замечательной и очень хотела бы, чтобы это демо работало.
Спасибо большое!
1 ответ
Здравствуйте, user9314395: удостоверение управляемой службы работает только с ресурсами, работающими в Azure. Хотя мы не поддерживаем сценарий локальной разработки, вы можете рассмотреть возможность использования следующей библиотеки (предварительного просмотра): https://docs.microsoft.com/en-us/azure/key-vault/service-to-service-authentication