Службе приложений Azure Active Directory не удается подключиться к Azure Keyvault с помощью учетных данных/токена пользователя

Я пытаюсь создать веб-приложение, в котором пользователь может просматривать секретную информацию Azure Keyvault, к которой явно имеет доступ их учетная запись Azure Ad. По сути, это панель мониторинга Azure Keyvault. Я использую проверку подлинности Azure Active Directory, когда пользователь входит в приложение. Это приложение размещается как служба приложений Azure.

Сама проверка подлинности Azure Active Directory работает нормально, но когда я пытаюсь подключиться к Azure Keyvault с помощью SecretClient и DefaultAzureCredential из Azure, она не работает.

Вот код, который я использую для сбора секретной информации:

var client = new SecretClient(new Uri(this.azureKeyVaultSettings.Value.KeyVaultBaseUrl),
                                      new DefaultAzureCredential(new DefaultAzureCredentialOptions()
                                                                 {
                                                                     ExcludeSharedTokenCacheCredential = false
                                                                 }));
                                                                     
var secrets = client.GetPropertiesOfSecretsAsync();

await foreach (SecretProperties secret in secrets)
{
    ...
}

Ниже приведен код, который у меня есть в Startup.cs. Я чувствую, что часть, которую мне не хватает, — это хранение токена, который я получаю после входа через oidc и каким-то образом использую его в SecretClient. Сначала я подумал, что это то, что EnableTokenAcquisitionToCallDownstreamApi и AddInMemoryTokenCaches делают ниже, и каким-то образом DefaultAzureCredential будет использовать это, но это явно не работает.

public void ConfigureServices(IServiceCollection services)
{
    ...
    
    services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
            .AddMicrosoftIdentityWebApp(this.Configuration,
                                        "AzureAd")
            .EnableTokenAcquisitionToCallDownstreamApi(new string[]
                                                       {
                                                           "user.read"
                                                       })
            .AddInMemoryTokenCaches();
    
    services.AddMvc(options =>
    {
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();
        options.Filters.Add(new AuthorizeFilter(policy));
    }).AddMicrosoftIdentityUI();
    
    ...

AppSettings.json:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mydomain.com",
    "TenantId": "c9db0b8f-****-****-****-************",
    "ClientId": "318b64c3-****-****-****-************",
    "ClientSecret": "vh27Q*********************",
    "CallbackPath": "/signin-oidc"
  },
  "AzureKeyVaultSettings": {
    "KeyVaultBaseUrl": "https://myspecialvault.vault.azure.net/"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Ошибки, которые я получаю в своей службе приложений Azure:

2022-03-19 11:32:49.842 +00:00 [Critical] AzureKeyVaultDashboard.Web.Controllers.HomeController: Azure.Identity.CredentialUnavailableException: DefaultAzureCredential failed to retrieve a token from the included credentials. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/defaultazurecredential/troubleshoot
- EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot- ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.- SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.- Visual Studio Token provider can't be accessed at D:\DWASFiles\Sites\myazkvdashboard\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json- Stored credentials not found. Need to authenticate user in VSCode Azure Account. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/vscodecredential/troubleshoot- Azure CLI not installed- PowerShell is not installed.---> System.AggregateException: Multiple exceptions were encountered while attempting to authenticate. (EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshoot) (ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.) (SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.) (Visual Studio Token provider can't be accessed at D:\DWASFiles\Sites\myazkvdashboard\LocalAppData\.IdentityService\AzureServiceAuth\tokenprovider.json) (Stored credentials not found. Need to authenticate user in VSCode Azure Account. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/vscodecredential/troubleshoot) (Azure CLI not installed) (PowerShell is not installed.)---> Azure.Identity.CredentialUnavailableException: EnvironmentCredential authentication unavailable. Environment variables are not fully configured. See the troubleshooting guide for more information. https://aka.ms/azsdk/net/identity/environmentcredential/troubleshootat Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(Exception ex, String additionalMessage)at Azure.Identity.EnvironmentCredential.GetTokenImplAsync(Boolean async, TokenRequestContext requestContext, CancellationToken cancellationToken)at Azure.Identity.EnvironmentCredential.GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)at Azure.Identity.DefaultAzureCredential.GetTokenFromSourcesAsync(TokenCredential[] sources, TokenRequestContext requestContext, Boolean async, CancellationToken cancellationToken)--- End of inner exception stack trace ------> (Inner Exception #1) Azure.Identity.CredentialUnavailableException: ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.---> System.AggregateException: Retry failed after 4 tries. Retry settings can be adjusted in ClientOptions.Retry. (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80)) (An attempt was made to access a socket in a way forbidden by its access permissions. (100.100.100.100:80))

Все эти функции работают нормально при локальном тестировании.

я использую

  • .нет 6
  • Azure.Identity — 1,5
  • Azure.Security.KeyVault.Secrets — 4.2

При регистрации вашего приложения (используется для аутентификации пользователей в вашем приложении) вы делегировали разрешение на хранилище ключей (в разрешениях API)?

Thomas 20.03.2022 08:22

@Thomas В моей регистрации приложения в разделе «Разрешения API» у меня есть запись для Azure Key Vault, где «Тип» разрешения настроен как «Делегированный», и в этом разрешении он также указан как «user_impersonation».

Cole W 20.03.2022 17:28

Это хорошее начало. Я думаю, вам нужно добавить эту область в вызов EnableTokenAcquisitionToCallDownstreamApi. Не уверен, что просто https://vault.azure.net/user_impersonation сработает, но, что еще хуже, попробуйте.

Thomas 20.03.2022 19:54

@ Томас Я добавил https://vault.azure.net/user_impersonation, но у меня все те же проблемы. Он работает локально, но когда я развертываю его как службу приложений Azure, я получаю те же ошибки, что и упомянутые выше, о том, что он не находит никаких токенов с DefaultAzureCredential

Cole W 21.03.2022 22:22
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
117
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

При развертывании хранилища ключей и службы приложений вы можете задать политику доступа в хранилище ключей для службы приложений, используя основной идентификатор службы приложений. Таким образом, веб-приложение, размещенное в службе приложений, получит доступ к хранилищу ключей. Вы можете использовать проверку подлинности Azure Ad для проверки подлинности пользователя, входящего в систему, а затем предоставить сведения о хранилище ключей в своем веб-приложении.

Пожалуйста, проверьте и прокомментируйте, работает ли это для вас.

Если вы говорите об использовании «Системы» или «Пользователя», назначенного управляемое удостоверение, я не хочу этого делать. Я хочу использовать права/роли пользователя Azure Active Directory. Именно так наша организация в настоящее время управляет доступом к секретам Azure KeyVault. Если бы я создал управляемое удостоверение, у него были бы другие уровни доступа, чем у пользователя Azure Active Directory (например, [email protected]).

Cole W 19.03.2022 17:08
Ответ принят как подходящий

Кажется, что DefaultAzureCredential не работает в моем случае. Мне пришлось внедрить объект ITokenAcquisition в мой конструктор и использовать ChainedCredential вот так, а не просто использовать DefaultAzureCredential:

var client = new SecretClient(new Uri(this.azureKeyVaultSettings.Value.KeyVaultBaseUrl),
                              new ChainedTokenCredential(new TokenAcquisitionTokenCredential(this.tokenAcquisition),
                                                               new DefaultAzureCredential());

var secrets = client.GetPropertiesOfSecretsAsync();

Мне также пришлось добавить https://vault.azure.net/user_impersonation к вызову .EnableTokenAcquisitionToCallDownstreamApi(). См. ниже исправление Startup.cs из моего исходного сообщения:

services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApp(this.Configuration,
                                    "AzureAd")
        .EnableTokenAcquisitionToCallDownstreamApi(new string[]
                                                   {
                                                       "https://vault.azure.net/user_impersonation",
                                                       "user.read"
                                                   })
        .AddInMemoryTokenCaches();

.EnableTokenAcquisitionToCallDownstreamApi() — это то, что позволяет внедрять ITokenAcquisition в контроллеры. Подробнее см. здесь:

https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-web-app-call-api-app-configuration?tabs=aspnetcore#startupcs

Приятно видеть, что у вас получилось заставить его работать :-0

Thomas 22.03.2022 04:39

Другие вопросы по теме