Я работаю над решением, которое в настоящее время выполняет код в Функциях Azure. Эти функции аутентифицируются для наших служб PaaS (Key Vault / Service Bus / Blob Storage и т. Д.) С использованием аутентификации 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 auth не будет работать в этом сценарии, поэтому я искал использовать 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, если я не прошел аутентификацию, но, опять же, мне нужно, чтобы мой принцип обслуживания был аутентифицирован, прежде чем я смогу получить к нему доступ.
Кто-нибудь делал этот подход раньше? Может быть, принцип обслуживания - неправильный подход?
Заранее благодарим за любые указатели!