Я работаю над решением, которое в настоящее время выполняет код в функциях Azure. Эти функции аутентифицируются в наших сервисах PaaS (хранилище ключей / служебная шина / хранилище BLOB-объектов и т. Д.) С использованием аутентификации MSI.
Код для аутентификации выглядит следующим образом:
// Connect to KeyVault in the context of the running code.
var tokenProvider = new AzureServiceTokenProvider();
var config = new ConfigurationBuilder().AddAzureKeyVault(
keyvaultUri,
new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback)),
new DefaultKeyVaultSecretManager())
.Build();
Это позволяет мне безопасно подключаться к служебной шине, используя такой код:
// Get ServiceBus connection settings.
config.GetSection("Messaging").Bind(ConfigSettings);
var namespaceName = Regex.Match(ConfigSettings.ConnectionString, @"Endpoint=sb:\/\/([^.]*)", RegexOptions.IgnoreCase).Groups[1].Value;
var token = tokenProvider.GetAccessTokenAsync("https://management.core.windows.net/", string.Empty).Result;
var tokenCredentials = new TokenCredentials(token);
var client = RestClient.Configure()
.WithEnvironment(AzureEnvironment.AzureGlobalCloud)
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.WithCredentials(new AzureCredentials(tokenCredentials, tokenCredentials, string.Empty, AzureEnvironment.AzureGlobalCloud))
.Build();
// Authenticate against Service Bus.
ServiceBusNamespace = Azure.Authenticate(client, string.Empty)
.WithSubscription(ConfigSettings.SubscriptionId)
.ServiceBusNamespaces.List()
.SingleOrDefault(n => n.Name == namespaceName);
Мы меняем наше решение, чтобы вместо запуска функций на ASE мы выполняли ту же операцию в консольном приложении (работающем в Linux). Очевидно, что аутентификация MSI не будет работать в этом сценарии, поэтому я искал использование AppId Service Priniple и AppSercret. Я устанавливаю Принцип в AAD следующим образом:

Этот код для использования этих Принципов обслуживания AppId и AppSecret выглядит следующим образом:
public async static Task<string> GetAccessToken(string tenantId, string appId, string appSecret)
{
var authenticationContext = new AuthenticationContext($"https://login.windows.net/{tenantId}");
var credential = new ClientCredential(clientId: appId, clientSecret: appSecret);
var result = await authenticationContext.AcquireTokenAsync(resource: "https://management.core.windows.net/", clientCredential: credential);
if (result == null) {
throw new InvalidOperationException("Failed to obtain the JWT token");
}
return result.AccessToken;
}
НО это требует, чтобы я держал подобные AppId, AppSecret и TenantId готовыми к использованию приложением. Я не хочу использовать AppSettings по очевидным причинам безопасности.
Теперь я могу запустить аутентификацию служебной шины, используя код, аналогичный тому, который был у меня ранее:
var namespaceName = Regex.Match(connectionString, @"Endpoint=sb:\/\/([^.]*)", RegexOptions.IgnoreCase).Groups[1].Value;
var tokenCredentials = new TokenCredentials(token);
var client = RestClient.Configure()
.WithEnvironment(AzureEnvironment.AzureGlobalCloud)
.WithLogLevel(HttpLoggingDelegatingHandler.Level.Basic)
.WithCredentials(new AzureCredentials(tokenCredentials, tokenCredentials, string.Empty, AzureEnvironment.AzureGlobalCloud))
.Build();
var serviceBusNamespace = Azure.Authenticate(client, string.Empty)
.WithSubscription(subscriptionId)
.ServiceBusNamespaces.List()
.SingleOrDefault(n => n.Name == namespaceName);
if (serviceBusNamespace == null)
{
throw new InvalidOperationException($"Couldn't find the service bus namespace {namespaceName} in the subscription with ID {subscriptionId}");
}
Мой вопрос - кажется бесполезным беспокоиться о безопасности и затем сохранять необходимые поля конфигурации (AppId, AppSecret, TenantId) в config или Env Vars. У меня есть другие варианты? Я не могу использовать KeyVault, пока я не аутентифицировался, но, опять же, мне требуется аутентификация моего Принципа обслуживания, прежде чем я смогу получить к нему доступ.
Кто-нибудь делал такой подход раньше? Может быть, принцип обслуживания - не правильный подход?
Заранее спасибо за любые указатели!