Рекомендации по проверке подлинности с помощью библиотеки удостоверений Azure для .NET

В этой статье приведены рекомендации по повышению производительности и надежности приложений .NET при проверке подлинности в службах Azure. Чтобы максимально эффективно использовать библиотеку идентификации Azure для .NET, важно понимать потенциальные проблемы и методы их устранения.

Использование детерминированных учетных данных в рабочих средах

DefaultAzureCredential — это наиболее простой способ начать работу с библиотекой идентификации Azure, но такое удобство связано с определёнными компромиссами. В частности, нельзя заранее гарантировать, какие именно учетные данные в цепочке будут успешно использованы для аутентификации запроса. В рабочей среде эта непредсказуемость может привести к значительным и иногда тонким проблемам.

Например, рассмотрим следующую гипотетическую последовательность событий:

  1. Группа безопасности организации предписывает всем приложениям использовать управляемое удостоверение для проверки подлинности в ресурсах Azure.
  2. В течение нескольких месяцев приложение .NET, размещенное на виртуальной машине Azure, успешно использует DefaultAzureCredential для проверки подлинности с помощью управляемого удостоверения.
  3. Не сообщая группе поддержки, разработчик устанавливает Azure CLI на этой виртуальной машине и запускает команду az login для проверки подлинности в Azure.
  4. Из-за отдельного изменения конфигурации в среде Azure проверка подлинности через исходное управляемое удостоверение неожиданно начинает терпеть неудачу без предупреждений.
  5. DefaultAzureCredential пропускает неудачные ManagedIdentityCredential и ищет следующие доступные учетные данные, AzureCliCredential.
  6. Приложение начинает использовать учетные данные Azure CLI, а не управляемое удостоверение, что может привести к сбою или неожиданному повышению или сокращению привилегий.

Чтобы предотвратить возникновение таких скрытых проблем или незаметных сбоев в рабочих приложениях, замените DefaultAzureCredential на конкретную реализацию TokenCredential, например, ManagedIdentityCredential. См. список производных для вариантов.

Например, рассмотрим следующую конфигурацию в проекте ASP.NET Core. Экземпляр DefaultAzureCredential неявно создается и используется для всех зарегистрированных клиентов сервисов.

DefaultAzureCredential credential = new();
BlobServiceClient client = new(
    new Uri($"https://{storageAccountName}.blob.core.windows.net"),
    credential);

Измените предыдущий код, чтобы выбрать учетные данные в зависимости от среды, в которой выполняется приложение:

builder.Services.AddAzureClients(clientBuilder =>
{
    clientBuilder.AddSecretClient(
        new Uri($"https://{keyVaultName}.vault.azure.net"));
    clientBuilder.AddBlobServiceClient(
        new Uri($"https://{storageAccountName}.blob.core.windows.net"));

    TokenCredential credential;

    if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
    {
        string? clientId = builder.Configuration["UserAssignedClientId"];
        credential = new ManagedIdentityCredential(
            ManagedIdentityId.FromUserAssignedClientId(clientId));
    }
    else
    {
        // local development environment
        credential = new ChainedTokenCredential(
            new VisualStudioCredential(),
            new AzureCliCredential(),
            new AzurePowerShellCredential());
    }

    clientBuilder.UseCredential(credential);
});

В этом примере в рабочей среде используется только ManagedIdentityCredential. Затем требования к проверке подлинности локальной среды разработки обслуживаются последовательностью учетных данных, определенных в предложении else.

Повторное использование экземпляров учетных данных

Повторно используйте экземпляры учетных данных, если это возможно, чтобы повысить устойчивость приложения и уменьшить количество запросов на маркеры доступа, выданных идентификатору Microsoft Entra. При повторном использовании учетных данных предпринимается попытка получить токен из кэша токенов приложения, управляемого зависимостью MSAL. Детальную информацию см. в разделе Кэширование токенов в клиентской библиотеке удостоверений Azure.

Важный

Приложение с большим объемом данных, которое не использует учетные данные повторно, может столкнуться с ответами об ограничении HTTP 429 от Microsoft Entra ID, что может привести к сбоям в работе приложений.

Рекомендуемая стратегия повторного использования учетных данных отличается типом приложения .NET.

Чтобы реализовать повторное использование учетных данных, используйте метод UseCredential из Microsoft.Extensions.Azure. Рассмотрим приложение ASP.NET Core, размещенное в Azure App Service в средах производства и промежуточной эксплуатации. Переменная среды ASPNETCORE_ENVIRONMENT установлена в Production или Staging, чтобы различать эти две среды неразработки. В рабочих и промежуточных средах пользовательский вариант ManagedIdentityCredential используется для аутентификации клиентов хранилища секретов Key Vault и хранилища BLOB-объектов.

При запуске приложения на локальной машине разработки, если ASPNETCORE_ENVIRONMENT установлено в Development, используется цепочка учетных данных инструментов разработчика. Этот подход гарантирует использование учетных данных, подходящих для среды, повышение безопасности и упрощение управления учетными данными.

builder.Services.AddAzureClients(clientBuilder =>
{
    clientBuilder.AddSecretClient(
        new Uri($"https://{keyVaultName}.vault.azure.net"));
    clientBuilder.AddBlobServiceClient(
        new Uri($"https://{storageAccountName}.blob.core.windows.net"));

    TokenCredential credential;

    if (builder.Environment.IsProduction() || builder.Environment.IsStaging())
    {
        string? clientId = builder.Configuration["UserAssignedClientId"];
        credential = new ManagedIdentityCredential(
            ManagedIdentityId.FromUserAssignedClientId(clientId));
    }
    else
    {
        // local development environment
        credential = new ChainedTokenCredential(
            new VisualStudioCredential(),
            new AzureCliCredential(),
            new AzurePowerShellCredential());
    }

    clientBuilder.UseCredential(credential);
});

Сведения об этом подходе в приложении ASP.NET Core см. в разделе Аутентификация с помощью идентификатора Microsoft Entra ID.

Понимание, когда необходимо время существования маркера и логика кэширования

Если вы используете учетные данные библиотеки удостоверений Azure вне контекста клиентской библиотеки пакета SDK Azure, зависящей от Azure Core, вы несете ответственность за управление временем существования токена и поведением кэширования в приложении.

Свойство RefreshOn в AccessToken, которое предоставляет указание пользователям относительно того, когда можно попытаться обновить токен, будет автоматически использоваться клиентскими библиотеками Azure SDK, которые зависят от библиотеки Azure Core для обновления токена. Для прямого использования библиотеки идентификации Azure , учетные данные которой поддерживают кэширование маркеров, базовый кэш MSAL автоматически обновляется заблаговременно при наступлении RefreshOn. Эта конструкция позволяет клиентскому коду вызывать GetToken каждый раз, когда требуется токен, и делегировать обновление библиотеке.

Чтобы вызывать GetToken только при необходимости, следите за датой RefreshOn и своевременно попытайтесь обновить токен после этого времени. Конкретная реализация зависит от клиента.

Понимание стратегии повторных попыток управляемой идентичности

Библиотека удостоверений Azure для .NET позволяет проходить проверку подлинности с помощью управляемого удостоверения с помощью ManagedIdentityCredential. Режим, в котором вы используете ManagedIdentityCredential, влияет на применяемую стратегию повторных попыток.

Режим быстрого отказа

  • Когда следует использовать: Для локальных сценариев разработки, в которых требуется быстрая обратная связь
  • Как активировать: Используйте DefaultAzureCredential один из следующих способов:
    • Без настройки переменной среды AZURE_TOKEN_CREDENTIALS
    • Если для переменной среды AZURE_TOKEN_CREDENTIALS установлено значение, отличное от ManagedIdentityCredential
  • Как это работает: Повторные попытки не выполняются, когда начальная попытка получения токена проваливается или истекает по времени ожидания по прошествии короткого времени. Это наименее устойчивый режим, так как он оптимизирован для быстрого сбоя для эффективного внутреннего цикла разработки.

Устойчивый режим

  • Когда следует использовать: В рабочих сценариях, где важна устойчивость

  • Как активировать: Выполните один из следующих подходов:

    • Использование DefaultAzureCredential с переменной среды, для которой AZURE_TOKEN_CREDENTIALS задано значение ManagedIdentityCredential

      Важный

      Этот DefaultAzureCredential подход работает только в отказоустойчивом режиме при использовании Azure.Identity пакета версии 1.16.0 или более поздней. В более ранних версиях этот подход действует по принципу "быстрая ошибка".

    • Используйте ChainedTokenCredential, содержащий ManagedIdentityCredential

    • Используйте ManagedIdentityCredential напрямую

  • Как это работает: Интервал времени между повторными запросами начинается с 0,8 секунды, по умолчанию используется не более пяти повторных запросов с экспоненциальным увеличением. Этот режим оптимизирован для устойчивости, но приводит к потенциально нежелательным задержкам во внутреннем цикле разработки.

    Чтобы изменить параметры повторных попыток по умолчанию, используйте Retry свойство в DefaultAzureCredentialOptions или ManagedIdentityCredentialOptions. Например, повторите попытку не более трех раз с начальным интервалом в 0,5 секунды:

    ManagedIdentityCredentialOptions miCredentialOptions = new(
            ManagedIdentityId.FromUserAssignedClientId(clientId)
        )
        {
            Retry =
            {
                MaxRetries = 3,
                Delay = TimeSpan.FromSeconds(0.5),
            }
        };
    
    ManagedIdentityCredential miCredential = new(miCredentialOptions);
    

    Дополнительные сведения о настройке политик повторных попыток см. в разделе Настройка настраиваемой политики повторных попыток.