Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Кэширование маркеров повышает производительность приложений, надежность и взаимодействие с пользователем. Microsoft. Identity.Web предоставляет гибкие стратегии кэширования, которые балансирует производительность, сохраняемость и надежность эксплуатации.
Обзор
В этом разделе описывается, какие токены кэширует Microsoft.Identity.Web и почему кэширование важно для вашего приложения.
Какие маркеры кэшируются?
Microsoft. Identity.Web кэширует несколько типов токенов:
| Тип маркера | размера | Объем | Выселения |
|---|---|---|---|
| Маркеры доступа | ~2 КБ | За (user/app, tenant, resource) | Автоматическое (на основе времени жизни) |
| Токены обновления | Variable | Учетная запись пользователя | Вручную или на основе правил |
| Токены идентификатора | ~2-7 КБ | На пользователя | Автоматический |
Где применяется кэширование маркеров:
- Веб-приложения, вызывающие API - маркеры пользователей для делегированного доступа
- Вызов downstream API с использованием маркеров OBO (требуются тщательные правила вытеснения)
- Демон-приложения — токены только для приложений для вызовов от сервиса к сервису
Почему кешировать токены?
Преимущества производительности:
- Уменьшает количество обратных запросов к Microsoft Entra ID
- Более быстрые вызовы API (L1: 10 мс и L2: <~30 мс и сеть: >100 мс)
- Низкая задержка для конечных пользователей
Преимущества надежности:
- Продолжает работать во время временных Microsoft Entra сбоев
- Устойчивость к временным возмущениям в сети
- Плавная деградация при сбое распределенного кэша
Преимущества затрат:
- Уменьшает запросы проверки подлинности (избежание регулирования)
- Более низкие Azure затраты на операции проверки подлинности
Быстрый старт
Быстро приступить к работе с одной из следующих конфигураций кэша в зависимости от среды.
Разработка: кэш в памяти
В следующем примере добавляется кэш токенов в памяти, подходящий для разработки и примеров:
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
Преимущества.
- Простая настройка
- Быстрая производительность
- Нет внешних зависимостей
Недостатки:
- Кэш теряется при перезапуске приложения. В веб-приложении пользователи остаются вошедыми через файл cookie, но должны повторно войти, чтобы получить маркер доступа и повторно заполнить кэш.
- Не подходит для рабочих развертываний с несколькими серверами
- Не делится между экземплярами приложений
Производственная среда — распределенный кэш
Для рабочих приложений, особенно развертываний с несколькими серверами, используйте распределенный кэш, поддерживаемый Redis или другим поставщиком:
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
// Choose your cache implementation
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "MyApp_";
});
Преимущества.
- Сохраняется при перезапусках приложения
- Общий для всех экземпляров приложения
- Автоматическое кэширование L1+L2
Недостатки:
- Требуется инфраструктура внешнего кэша
- Дополнительная сложность конфигурации
- Задержка сети для операций кэша
Выбор стратегии кэширования
Используйте следующую блок-схему принятия решений и матрицу, чтобы выбрать стратегию кэша, которая лучше всего подходит для развертывания.
flowchart TD
Start([Token Caching<br/>Decision]) --> Q1{Production<br/>Environment?}
Q1 -->|No - Dev/Test| DevChoice[In-Memory Cache<br/>AddInMemoryTokenCaches]
Q1 -->|Yes| Q2{Multiple Server<br/>Instances?}
Q2 -->|No - Single Server| Q3{App Restarts<br/>Acceptable?}
Q3 -->|Yes| DevChoice
Q3 -->|No| DistChoice
Q2 -->|Yes| DistChoice[Distributed Cache<br/>AddDistributedTokenCaches]
DistChoice --> Q4{Cache<br/>Implementation?}
Q4 -->|High Performance| Redis[Redis Cache<br/>StackExchange.Redis<br/>⭐ Recommended]
Q4 -->|Azure Native| Azure[Azure Cache for Redis,<br/>Azure Cosmos DB,<br/>or Azure Database for PostgreSQL]
Q4 -->|On-Premises| SQL[SQL Server Cache<br/>AddDistributedSqlServerCache]
Q4 -->|Testing| DistMem[Distributed Memory<br/>Not for production]
Redis --> L1L2[Automatic L1+L2<br/>Caching]
Azure --> L1L2
SQL --> L1L2
DistMem --> L1L2
L1L2 --> Config[Configure Options<br/>MsalDistributedTokenCacheAdapterOptions]
DevChoice --> MemConfig[Configure Memory Options<br/>MsalMemoryTokenCacheOptions]
style Start fill:#e1f5ff
style DevChoice fill:#d4edda
style DistChoice fill:#fff3cd
style Redis fill:#d1ecf1
style L1L2 fill:#f8d7da
Матрица принятия решений
В следующей таблице приведены рекомендуемые типы кэша для распространенных сценариев развертывания.
| Сценарий | Рекомендуемый кэш | Логическое обоснование |
|---|---|---|
| Локальная разработка | In-Memory | Простота, инфраструктура не требуется |
| Примеры и демонстрации | In-Memory | Простая настройка демонстраций |
| Продакшн с одним сервером (перезапуски допустимы) | In-Memory | Допустимо, если сеансы можно повторно установить |
| Рабочая среда с несколькими серверами | Редис | Общий кэш, высокая производительность, надежная |
| Приложения, размещенные в Azure | Кэш Azure для Redis | Нативная интеграция с Azure, управляемая услуга |
| Локальное предприятие | SQL Server | Использует существующую инфраструктуру |
| Среды PostgreSQL | PostgreSQL | Использует существующую базу данных PostgreSQL, знакомую семантику SQL |
| Высокобезопасные среды | SQL Server + шифрование | Размещение данных, шифрование данных в состоянии покоя |
| Тестирование распределенных сценариев | Распределенная память | Проверяет поведение кэша L2 без инфраструктуры |
Реализации кэша
Microsoft. Identity.Web поддерживает несколько реализаций кэша. Выберите ту, которая соответствует требованиям к инфраструктуре и доступности.
Кэш в памяти
Когда следует использовать:
- Разработка и тестирование
- Развертывания с одним сервером с допустимым поведением перезапуска
- Примеры и прототипы
Configuration:
Следующий код регистрирует кэш маркеров в памяти с параметрами по умолчанию:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
С настраиваемыми параметрами:
Вы можете настроить ограничения срока действия и размера, передав параметры:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches(options =>
{
// Token cache entry will expire after this duration
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1);
// Limit cache size (default is unlimited)
options.SizeLimit = 500 * 1024 * 1024; // 500 MB
});
→ Дополнительные сведения о конфигурации кэша в памяти
Распределенный кэш (L2) с автоматической поддержкой L1
Когда следует использовать:
- Развертывания на многосерверных промышленных средах
- Приложения, требующие сохраняемости кэша при перезапуске
- Сценарии с высоким уровнем доступности
Основная функция: Начиная с версии 1.8.0 Microsoft.Identity.Web, распределённый кэш автоматически включает кэш L1 в памяти для повышения производительности и надёжности.
Кэш Redis (рекомендуется)
Добавьте строку подключения Redis в appsettings.json:
{
"ConnectionStrings": {
"Redis": "localhost:6379"
}
}
Затем зарегистрируйте распределенный кэш токенов и поставщик Redis в Program.cs:
using Microsoft.Identity.Web;
using Microsoft.Identity.Web.TokenCacheProviders.Distributed;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
// Redis cache implementation
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "MyApp_"; // Unique prefix per application
});
// Optional: Configure distributed cache behavior
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Control L1 cache size
options.L1CacheOptions.SizeLimit = 500 * 1024 * 1024; // 500 MB
// Handle L2 cache failures gracefully
options.OnL2CacheFailure = (exception) =>
{
if (exception is StackExchange.Redis.RedisConnectionException)
{
// Log the failure
// Optionally attempt reconnection
return true; // Retry the operation
}
return false; // Don't retry
};
});
Кэш Azure для Redis
Чтобы использовать Кэш Azure для Redis, зарегистрируйте кэш с помощью строки подключения Azure.
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("AzureRedis");
options.InstanceName = "MyApp_";
});
Формат строки подключения:
<cache-name>.redis.cache.windows.net:6380,password=<access-key>,ssl=True,abortConnect=False
кэш SQL Server
Следующий пример настраивает SQL Server в качестве бэкенда распределенного кэша.
builder.Services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("TokenCacheDb");
options.SchemaName = "dbo";
options.TableName = "TokenCache";
// Set expiration longer than access token lifetime (default 1 hour)
// This prevents cache entries from expiring before tokens
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
кэш Azure Cosmos DB
Следующий пример настраивает Azure Cosmos DB в качестве серверной платформы для распределенного кэша.
builder.Services.AddCosmosCache((CosmosCacheOptions options) =>
{
options.ContainerName = builder.Configuration["CosmosCache:ContainerName"];
options.DatabaseName = builder.Configuration["CosmosCache:DatabaseName"];
options.ClientBuilder = new CosmosClientBuilder(
builder.Configuration["CosmosCache:ConnectionString"]);
options.CreateIfNotExists = true;
});
Кэш PostgreSQL
Требуется пакет NuGet Microsoft.Extensions.Caching.Postgres.
appsettings.json:
{
"ConnectionStrings": {
"PostgresCache": "Host=localhost;Database=mydb;Username=myuser;Password=mypassword"
},
"PostgresCache": {
"SchemaName": "public",
"TableName": "token_cache",
"CreateIfNotExists": true
}
}
Затем зарегистрируйте кэш PostgreSQL в Program.cs:
builder.Services.AddDistributedPostgresCache(options =>
{
options.ConnectionString = builder.Configuration.GetConnectionString("PostgresCache");
options.SchemaName = builder.Configuration["PostgresCache:SchemaName"];
options.TableName = builder.Configuration["PostgresCache:TableName"];
options.CreateIfNotExists = builder.Configuration.GetValue<bool>("PostgresCache:CreateIfNotExists");
options.DefaultSlidingExpiration = TimeSpan.FromMinutes(90);
});
→ Дополнительные сведения о конфигурации распределенного кэша
Кэш сеансов (не рекомендуется)
Предостережение
Кэширование на основе сеансов имеет значительные ограничения. Вместо этого используйте распределенный кэш.
В следующем примере показано кэширование токенов, основанное на сеансе, в качестве примера.
using Microsoft.Identity.Web.TokenCacheProviders.Session;
// In Program.cs
builder.Services.AddSession();
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddSessionTokenCaches();
// In middleware pipeline
app.UseSession(); // Must be before UseAuthentication()
app.UseAuthentication();
app.UseAuthorization();
Limitations:
- Проблемы с размером файла cookie — большие маркеры идентификатора с множеством утверждений вызывают проблемы
- Конфликты области видимости Scope — не удается использовать с одноэлементным объектом
TokenAcquisition(например, пакет SDK Microsoft Graph) - Требуется сопоставление сеансов . Не работает хорошо в сценариях балансировки нагрузки
- Не рекомендуется . Вместо этого используйте распределенный кэш
Расширенная конфигурация
Эти параметры позволяют точно настроить поведение кэша для политик производительности, безопасности и вытеснения.
Элемент управления кэшем L1
Кэш L1 (в памяти) повышает производительность при использовании распределенных кэшей. Следующий код настраивает размер и поведение кэша L1:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Control L1 cache size (default: 500 MB)
options.L1CacheOptions.SizeLimit = 100 * 1024 * 1024; // 100 MB
// Disable L1 cache if session affinity is not available
// (forces all requests to use L2 cache for consistency)
options.DisableL1Cache = false;
});
Когда отключить L1:
- Отсутствие привязки сеансов в балансировщике нагрузки
- Пользователи часто запрашивают MFA из-за несоответствия кэша
- Компромисс: доступ L2 медленнее (~30 мс и ~10 мс)
Политики удаления кэша
Политики вытеснения управляют удалением токенов из кэша. Следующий код задает абсолютный и скользящий срок действия:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
// Absolute expiration (removed after this time, regardless of use)
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(72);
// Sliding expiration (renewed on each access)
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Вы также можете настроить вытеснение с помощью appsettings.json:
{
"TokenCacheOptions": {
"AbsoluteExpirationRelativeToNow": "72:00:00",
"SlidingExpiration": "02:00:00"
}
}
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(
builder.Configuration.GetSection("TokenCacheOptions"));
Рекомендации.
- Установите срок действия дольше, чем срок действия токена (обычно срок действия токенов истекает через 1 час)
- По умолчанию: 90 минут скользящего срока действия
- Баланс между использованием памяти и взаимодействием с пользователем
- Рассмотрим: 72 часа абсолютно + 2 часа скольжения для хорошего пользовательского интерфейса
→ Дополнительные сведения о стратегиях вытеснения кэша
Шифрование данных в состоянии покоя
Чтобы защитить данные конфиденциального токена в распределенных кэшах, включите шифрование с помощью ASP.NET Core Data Protection.
Одна машина
На одном компьютере включите шифрование со встроенным поставщиком защиты данных:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = true; // Uses ASP.NET Core Data Protection
});
Распределенные системы (несколько серверов)
Это важно
Распределенные системы по умолчанию не совместно используют ключи шифрования. Необходимо настроить общий доступ к ключам:
Azure Key Vault (рекомендуется):
Следующий код сохраняет ключи для Хранилище BLOB-объектов Azure и защищает их с помощью Azure Key Vault:
using Microsoft.AspNetCore.DataProtection;
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(new Uri(builder.Configuration["DataProtection:BlobUri"]))
.ProtectKeysWithAzureKeyVault(
new Uri(builder.Configuration["DataProtection:KeyIdentifier"]),
new DefaultAzureCredential());
На основе сертификата:
Следующий код сохраняет ключи в общей папке и защищает их с помощью сертификата X.509:
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(
new X509Certificate2("current.pfx", builder.Configuration["CertPassword"]))
.UnprotectKeysWithAnyCertificate(
new X509Certificate2("current.pfx", builder.Configuration["CertPassword"]),
new X509Certificate2("previous.pfx", builder.Configuration["PrevCertPassword"]));
→ Дополнительные сведения о шифровании и защите данных
Рекомендации по производительности кэша
Используйте следующие оценки для планирования емкости кэша для приложения.
Оценки размера токена
| Тип маркера | Стандартный размер | За | Примечания |
|---|---|---|---|
| Маркеры приложений | ~2 КБ | Арендатор × ресурс | Автоматическое вытеснение |
| Токены пользователей | ~7 КБ | Пользователь × Арендатор × Ресурс | Необходимо вытеснение вручную |
| Маркеры обновления | Variable | User | Долгоживущий |
Планирование памяти
Для 500 одновременных пользователей , вызывающих 3 API:
- Токены пользователя: 500 × 3 × 7 КБ = 10,5 МБ
- С накладными расходами: ~15-20 МБ
Для 10 000 одновременных пользователей:
- Маркеры пользователей: 10 000 × 3 × 7 КБ = 210 МБ
- С учётом накладных расходов: ~300-350 МБ
Рекомендации: Задайте ограничение размера кэша L1 на основе ожидаемых одновременных пользователей.
Лучшие практики
Следуйте этим рекомендациям, чтобы обеспечить надежное и эффективное кэширование токенов.
Использование распределенного кэша в рабочей среде — Essential для развертываний с несколькими серверами
Установка соответствующих ограничений размера кэша — предотвращение роста несвязанной памяти
Настройка политик вытеснения — балансировка использования пользовательского интерфейса и памяти
Включение шифрования конфиденциальных данных — защита токенов в состоянии покоя
Мониторинг работоспособности кэша — отслеживание частоты попаданий, сбоев и производительности
Корректная обработка сбоев кэша L2. Кэш L1 обеспечивает устойчивость.
Поведение кэша — проверка сценариев перезапуска и переключения на резерв
Не используйте кэш распределенной памяти в рабочей среде — не сохраняемый или распределенный
Не используйте кэш сеансов . Имеет значительные ограничения
Не устанавливайте срок действия меньше времени существования маркера – приводит к ненужной повторной проверке подлинности.
Не забывайте о совместном использовании ключей шифрования . Распределенные системы нуждаются в общих ключах