Получение маркера из кэша маркеров с помощью MSAL.NET

Когда вы получаете маркер доступа с помощью Microsoft Authentication Library для .NET (MSAL.NET), этот маркер кэшируется. Когда приложению требуется маркер, сначала необходимо попытаться получить его из кэша.

Источник токенов можно определить, проверив свойство AuthenticationResult.AuthenticationResultMetadata.TokenSource.

Веб-сайты и веб-API

ASP.NET Core и классические веб-сайты ASP.NET должны интегрироваться с Microsoft. Identity.Web — оболочка для MSAL.NET. Кэширование маркеров памяти или кэширование распределенных маркеров можно настроить, как описано в сериализации кэша маркеров.

Веб-API в ASP.NET Core должны использовать Microsoft. Identity.Web. Веб-API на классической ASP.NET используют MSAL напрямую, путем вызова AcquireTokenOnBehalfOf, и для них следует настроить кэширование в памяти или распределенное кэширование. Дополнительные сведения см. в разделе сериализация кэша маркеров в MSAL.NET. Нет причин вызывать AcquireTokenSilent API, так как нет API для очистки кэша. Размер кэша можно управлять путем установки политик вытеснения в базовом хранилище кэша, таких как MemoryCache, Redis и т. д.

Веб-служба или приложения управляющей программы

Приложения, запрашивающие токены для удостоверения приложения без участия пользователя, вызывая AcquireTokenForClient, могут либо полагаться на внутреннее кэширование MSAL, либо определять собственное кэширование токенов в памяти или распределённое кэширование токенов. Инструкции и дополнительные сведения см. в статье о сериализации кэша маркеров в MSAL.NET.

Так как пользователь не участвует, нет причин для вызова AcquireTokenSilent. AcquireTokenForClient самостоятельно проверит кэш, поскольку API для его очистки отсутствует. Размер кэша пропорционален количеству арендаторов и ресурсов, для которых вам нужны токены. Размер кэша можно управлять, задав политики вытеснения в базовом хранилище кэша, например MemoryCache, Redis и т. д.

Настольные, консольные и мобильные приложения

Классические, командные строки и мобильные приложения должны сначала вызвать AcquireTokenSilent метод, чтобы проверить, находится ли допустимый маркер в кэше. Во многих случаях можно получить другой токен с дополнительными областями действия на основе токена, хранящегося в кэше. Кроме того, можно обновить маркер, когда он приближается к истечении срока действия (так как кэш маркеров также содержит маркер обновления).

Для потоков аутентификации, требующих взаимодействия с пользователем, MSAL кэширует маркеры доступа, обновления и идентификации, а также объект IAccount, который представляет информацию об одной учетной записи. Дополнительные сведения об IAccount. Для потоков приложений, таких как учетные данные клиента, в кэше сохраняются только токены доступа, поскольку объект IAccount и ID-токен требуют пользователя, а токен обновления неприменим.

Рекомендуемый шаблон — сначала вызвать AcquireTokenSilent метод. Если AcquireTokenSilent завершается сбоем, получите маркер с помощью других методов.

В следующем примере приложение сначала пытается получить маркер из кэша маркеров. Если возникает исключение MsalUiRequiredException, приложение получает токен в интерактивном режиме.

var accounts = await app.GetAccountsAsync();

AuthenticationResult result = null;
try
{
     result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault())
                       .ExecuteAsync();
}
catch (MsalUiRequiredException ex)
{
    // A MsalUiRequiredException happened on AcquireTokenSilent.
    // This indicates you need to call AcquireTokenInteractive to acquire a token
    Debug.WriteLine($"MsalUiRequiredException: {ex.Message}");

    try
    {
        result = await app.AcquireTokenInteractive(scopes)
                          .ExecuteAsync();
    }
    catch (MsalException msalex)
    {
        ResultText.Text = $"Error Acquiring Token:{System.Environment.NewLine}{msalex}";
    }
}
catch (Exception ex)
{
    ResultText.Text = $"Error Acquiring Token Silently:{System.Environment.NewLine}{ex}";
    return;
}

if (result != null)
{
    string accessToken = result.AccessToken;
    // Use the token
}

Очистка кэша

В общедоступных клиентских приложениях удаление учетных записей из кэша очищает его. Однако это не удаляет файл cookie сеанса, который находится в браузере.

var accounts = (await app.GetAccountsAsync()).ToList();

// clear the cache
while (accounts.Any())
{
   await app.RemoveAsync(accounts.First());
   accounts = (await app.GetAccountsAsync()).ToList();
}