Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O cache de tokens melhora o desempenho do aplicativo, a confiabilidade e a experiência do usuário. Microsoft. O Identity.Web fornece estratégias de cache flexíveis que equilibram o desempenho, a persistência e a confiabilidade operacional.
Visão geral
Esta seção descreve quais tokens o Microsoft.Identity.Web armazena em cache e por que o armazenamento em cache é importante para seu aplicativo.
Quais tokens são armazenados em cache?
Microsoft. Identity.Web armazena em cache vários tipos de tokens:
| Tipo de token | Tamanho | Scope | Despejo |
|---|---|---|---|
| Tokens de acesso | ~2 KB | Por (usuário/aplicativo, locatário, recurso) | Automático (baseado em tempo de vida) |
| Atualizar tokens | Variable | Por conta de usuário | Manual ou baseado em política |
| ID Tokens | ~2-7 KB | Por usuário | Automático |
Onde o cache de token se aplica:
- Aplicativos Web chamando APIs – Tokens de usuário para acesso delegado
- APIs Web que chamam APIs downstream – tokens OBO (requer políticas de remoção cuidadosas)
- Daemon Applications – tokens exclusivos de aplicativo para chamadas de serviço a serviço
Por que armazenar tokens em cache?
Benefícios de desempenho:
- Reduz as viagens de ida e volta para Microsoft Entra ID
- Chamadas de API mais rápidas (L1: <10ms vs L2: ~30ms versus rede: >100ms)
- Latência mais baixa para usuários finais
Benefícios de confiabilidade:
- Continua trabalhando durante interrupções temporárias do Microsoft Entra
- Resiliente a transitórios de rede
- Degradação normal quando o cache distribuído falha
Benefícios de custo:
- Reduz solicitações de autenticação (prevenção de limitação)
- Reduzir os custos de Azure para operações de autenticação
Início Rápido
Comece rapidamente com uma das seguintes configurações de cache, dependendo do seu ambiente.
Desenvolvimento – cache em memória
O exemplo a seguir adiciona um cache de token na memória, adequado para desenvolvimento e exemplos:
using Microsoft.Identity.Web;
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
Vantagens:
- Configuração simples
- Desempenho rápido
- Nenhuma dependência externa
Desvantagens:
- Cache perdido na reinicialização do aplicativo. Em um aplicativo Web, os usuários permanecem conectados por meio do cookie, mas devem entrar novamente para obter um token de acesso e preencher novamente o cache
- Não adequado para implantações de vários servidores de produção
- Não compartilhado entre instâncias de aplicativo
Produção – cache distribuído
Para aplicativos de produção, especialmente implantações de vários servidores, use um cache distribuído apoiado pelo Redis ou outro provedor:
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_";
});
Vantagens:
- Sobrevive às reinicializações do aplicativo
- Compartilhado em todas as instâncias do aplicativo
- Cache L1+L2 automático
Desvantagens:
- Requer infraestrutura de cache externo
- Complexidade de configuração adicional
- Latência de rede para operações de cache
Escolhendo uma estratégia de cache
Use o fluxograma de decisão e a matriz a seguir para selecionar a estratégia de cache que melhor se ajusta à sua implantação.
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
Matriz de decisão
A tabela a seguir resume os tipos de cache recomendados para cenários comuns de implantação.
| Scenario | Cache recomendado | Lógica |
|---|---|---|
| Desenvolvimento local | In-Memory | Simplicidade, nenhuma infraestrutura necessária |
| Exemplos/demonstrações | In-Memory | Configuração fácil para demonstrações |
| Produção de servidor único (reinicia OK) | In-Memory | Aceitável se as sessões puderem ser restabelecidas |
| Produção de vários servidores | Redis | Cache compartilhado, alto desempenho, confiável |
| aplicativos hospedados Azure | Cache do Azure para Redis | Integração de Azure nativa, serviço gerenciado |
| Empresa local | SQL Server | Aproveita a infraestrutura existente |
| Os ambientes PostgreSQL | PostgreSQL | Usa o banco de dados PostgreSQL existente, semântica familiar de SQL |
| Ambientes de alta segurança | SQL Server + Criptografia | Residência de dados, criptografia em repouso |
| Testando cenários distribuídos | Memória Distribuída | Testa o comportamento do cache L2 sem infraestrutura |
Implementações de cache
Microsoft. O Identity.Web dá suporte a várias implementações de cache. Escolha aquele que corresponda aos requisitos de infraestrutura e disponibilidade.
Cache na memória
Quando usar:
- Desenvolvimento e teste
- Implantações de servidor único com comportamento de reinicialização aceitável
- Exemplos e protótipos
Configuration:
O código a seguir registra o cache de token na memória com configurações padrão:
builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
Com opções personalizadas:
Você pode personalizar os limites de expiração e tamanho passando opções:
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
});
→ Saiba mais sobre a configuração de cache na memória
Cache distribuído (L2) com suporte automático de L1
Quando usar:
- Implantações de vários servidores de produção
- Aplicativos que exigem persistência de cache entre reinicializações
- Cenários de alta disponibilidade
Key feature: Desde Microsoft. Identity.Web v1.8.0, o cache distribuído inclui automaticamente um cache L1 na memória para desempenho e confiabilidade.
Cache Redis (recomendado)
Adicione a string de conexão Redis a appsettings.json:
{
"ConnectionStrings": {
"Redis": "localhost:6379"
}
}
Em seguida, registre o cache de token distribuído e o provedor Redis no 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
};
});
Cache do Azure para Redis
Para usar o Cache do Azure para Redis, registre o cache com a sua string de conexão do Azure.
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("AzureRedis");
options.InstanceName = "MyApp_";
});
Formato da cadeia de conexão:
<cache-name>.redis.cache.windows.net:6380,password=<access-key>,ssl=True,abortConnect=False
cache SQL Server
O exemplo a seguir configura SQL Server como o back-end do cache distribuído:
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);
});
cache do Azure Cosmos DB
O exemplo a seguir configura Azure Cosmos DB como o back-end do cache distribuído:
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;
});
Cache do PostgreSQL
Requer o pacote 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
}
}
Em seguida, registre o cache PostgreSQL no 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);
});
→ Saiba mais sobre a configuração de cache distribuído
Cache de sessão (não recomendado)
Cuidado
O cache baseado em sessão tem limitações significativas. Em vez disso, use um cache distribuído.
O exemplo a seguir mostra o cache de token baseado em sessão para referência:
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();
Limitações:
- Problemas de tamanho de cookie – Tokens de ID grandes com muitas declarações causam problemas
- conflitos Scope - Não é possível usar com singleton
TokenAcquisition(por exemplo, Microsoft Graph SDK) - Afinidade de sessão necessária – Não funciona bem em cenários com balanceamento de carga
- Não recomendado – Use o cache distribuído em vez disso
Configuração avançada
Essas opções permitem ajustar o comportamento do cache para políticas de desempenho, segurança e remoção.
Controle de cache L1
O cache L1 (na memória) melhora o desempenho quando você usa caches distribuídos. O código a seguir configura o tamanho e o comportamento do cache 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;
});
Quando desabilitar L1:
- Não há afinidade de sessão no balanceador de carga
- Usuários frequentemente solicitados a usar MFA por inconsistência no cache
- Compensação: O acesso L2 é mais lento (~30ms versus ~10ms)
Políticas de remoção de cache
As políticas de expurgação controlam quando os tokens armazenados em cache são removidos. O código a seguir define a expiração absoluta e deslizante:
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);
});
Você também pode configurar a evicção por meio de appsettings.json:
{
"TokenCacheOptions": {
"AbsoluteExpirationRelativeToNow": "72:00:00",
"SlidingExpiration": "02:00:00"
}
}
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(
builder.Configuration.GetSection("TokenCacheOptions"));
Recomendações:
- Definir expiração maior que o tempo de vida do token (os tokens normalmente expiram em 1 hora)
- Padrão: expiração deslizante de 90 minutos
- Balancear entre o uso de memória e a experiência do usuário
- Considere: 72 horas absolutas + 2 horas deslizantes para uma boa experiência do usuário
→ Saiba mais sobre estratégias de remoção de cache
Criptografia em repouso
Para proteger dados confidenciais de token em caches distribuídos, habilite a criptografia por meio da Proteção de Dados ASP.NET Core.
Única máquina
Em um único computador, habilite a criptografia com o provedor interno de Proteção de Dados:
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = true; // Uses ASP.NET Core Data Protection
});
Sistemas distribuídos (vários servidores)
Importante
Os sistemas distribuídos não compartilham chaves de criptografia por padrão. Você deve configurar o compartilhamento de chaves:
Azure Key Vault (recomendado):
O código a seguir persiste as chaves para Armazenamento de Blobs do Azure e as protege com 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());
Baseado em certificado:
O código a seguir persiste as chaves de um compartilhamento de arquivos e as protege com um certificado 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"]));
→ Saiba mais sobre criptografia e proteção de dados
Considerações sobre o desempenho do cache
Use as estimativas a seguir para planejar a capacidade de cache para seu aplicativo.
Estimativas de tamanho do token
| Tipo de token | Tamanho Típico | Por | Observações |
|---|---|---|---|
| Tokens de aplicativo | aproximadamente 2 KB | Locatário × Recurso | Removido automaticamente |
| Tokens de usuário | ~7 KB | Usuário × Locatário × Recurso | Remoção manual necessária |
| Tokens de atualização | Variable | Usuário | Vida longa |
Planejamento de memória
Para 500 usuários simultâneos que chamam 3 APIs:
- Tokens de usuário: 500 × 3 × 7 KB = 10,5 MB
- Com sobrecarga: ~15 a 20 MB
Para 10.000 usuários simultâneos:
- Tokens de usuário: 10.000 × 3 × 7 KB = 210 MB
- Com sobrecarga: ~300-350 MB
Recomendação: Defina o limite de tamanho do cache L1 com base nos usuários simultâneos esperados.
Práticas recomendadas
Siga estas diretrizes para garantir o cache de token confiável e eficiente.
Usar cache distribuído em produção – Essencial para implantações de vários servidores
Definir limites de tamanho de cache apropriados – impedir o crescimento ilimitado da memória
Configurar políticas de despejo – Balancear o uso de memória e UX
Habilitar a criptografia para dados confidenciais – Proteger tokens em repouso
Monitorar a integridade do cache – controlar taxas de ocorrência, falhas e desempenho
Lidar com falhas de cache L2 normalmente – o cache L1 garante resiliência
Testar o comportamento do cache – verificar os cenários de reinicialização e failover
Não usar cache de memória distribuída em produção – não persistente ou distribuído
Não usar cache de sessão – tem limitações significativas
Defina a expiração não menor que o tempo de vida do token – pois isso forçará a reautenticação desnecessária
Não se esqueça do compartilhamento de chaves de criptografia – os sistemas distribuídos precisam de chaves compartilhadas