Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este artigo ajuda-o a diagnosticar e resolver problemas de cache de tokens na Microsoft. Identidade.Web. Problemas com a cache dos tokens podem causar falhas de autenticação, desempenho degradado ou comandos inesperados para iniciar sessão. Para uma visão geral de como funciona o cache de tokens na Microsoft. Identity.Web, consulte Token cache overview.
Pré-requisitos
Antes de tentar resolver o problema, confirme o seguinte:
- Estás a usar uma versão suportada do Microsoft. Identidade.Web.
- A sua aplicação tem cache de tokens configurado em
Program.csouStartup.cs. - Tem acesso aos registos de aplicações e, se aplicável, à sua infraestrutura de cache distribuída.
Ativar o registo e diagnóstico da cache de tokens
Ative o registo detalhado como primeiro passo de diagnóstico. Microsoft. O Identity.Web utiliza a infraestrutura de registo ASP.NET Core e emite eventos através da Biblioteca de Autenticação da Microsoft (MSAL).
Ativar registo de MSAL
Defina o nível de log para Debug nas bibliotecas de identidade do seu appsettings.json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Subscrever eventos de cache MSAL
Subscreva os eventos de notificação da cache do token MSAL para acompanhar acertos, falhas e atividade de serialização:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
logger.LogWarning(ex, "L2 cache failure encountered.");
// Return true to allow the operation to continue despite the cache failure.
// Return false to propagate the exception.
return true;
};
});
Monitorizar métricas de cache
Para monitorização de produção, acompanhe estas métricas-chave:
- Taxa de acerto no cache — uma taxa de acerto baixa indica que os tokens não estão a ser recuperados do cache.
- Latência da cache L2 — alta latência sugere uma conectividade ou problema de desempenho na cache distribuída.
- Erros de serialização de cache — erros durante a leitura ou escrita indicam corrupção ou incompatibilidade de versões.
- Consumo de memória — o crescimento sustentado pode indicar a falta de políticas de expulsão.
Falhas de ligação à cache distribuída (L2)
Symptom
Os registos de aplicação mostram erros de timeout de ligação ou falhas intermitentes de autenticação. Os utilizadores experienciam atrasos ao iniciar sessão, e observa-se exceções como:
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache:
StackExchange.Redis.RedisConnectionException:
No connection is active/available to service this operation.
Ou, para cache distribuído do SQL Server:
Microsoft.Data.SqlClient.SqlException:
A network-related or instance-specific error occurred while
establishing a connection to SQL Server.
Motivo
O armazenamento distribuído de backup de cache (Redis ou SQL Server) é inacessível. As causas comuns incluem:
- cadeia de ligação incorreta ou credenciais de acesso expiradas.
- Regras de firewall de rede bloqueiam a ligação ao alojamento da app.
- O serviço de cache está fora de serviço ou em manutenção.
- Incompatibilidade de configuração SSL/TLS entre o cliente e o servidor de cache.
Passos de diagnóstico
Siga estes passos para identificar a falha da ligação:
- Verifica a conectividade. A partir do host da aplicação, teste a ligação ao Redis ou SQL Server usando
Test-NetConnection(PowerShell) ouredis-cli. - Verifica a cadeia de ligação. Confirme que a cadeia de ligação corresponde ao nome de host, porta e credenciais do servidor de cache.
- Revê as regras do firewall. No Azure, verifique se o serviço de aplicação ou a rede virtual consegue aceder ao recurso de cache.
- Verificar o estado de funcionamento do serviço. No portal Azure, reveja a saúde e as métricas da sua instância do Cache do Azure para Redis ou SQL Database.
Solução
Passo 1: Corrigir a cadeia de ligação
Verifique a cadeia de conexão no seu appsettings.json:
{
"ConnectionStrings": {
"Redis": "your-redis-instance.redis.cache.windows.net:6380,password=your-access-key,ssl=True,abortConnect=False"
}
}
Importante
Defina abortConnect=False na string de conexão do Redis. Esta configuração permite que a aplicação se reconecte automaticamente após falhas de ligação transitórias, em vez de ser lançada imediatamente.
Passo 2: Configurar repetição e resiliência
Configure o OnL2CacheFailure callback para que a sua aplicação se degrade de forma natural quando a cache distribuída estiver temporariamente indisponível:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
// Log the failure for monitoring and alerting.
logger.LogWarning(ex, "Distributed token cache is unavailable. " +
"Falling back to in-memory cache.");
return true; // Continue without the L2 cache.
};
// Set a timeout to avoid blocking the request pipeline.
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
});
Passo 3: Abrir regras de firewall
Se a aplicação correr no Serviço de Aplicações do Azure e a cache estiver numa rede virtual, adicione os endereços IP de saída do App Service à lista de permissões do firewall da cache.
Erros de desserialização da cache
Symptom
Depois de atualizares a Microsoft. Identity.Web ou MSAL.NET, a aplicação lança exceções de desserialização ao ler do cache distribuído. Os utilizadores têm de iniciar sessão novamente, e vê exceções como:
System.Text.Json.JsonException:
The JSON value could not be converted to the expected type.
Ou:
Microsoft.Identity.Client.MsalClientException:
Error code: json_parse_failed
Motivo
O formato de serialização da cache de token mudou entre as versões da biblioteca. Os tokens armazenados em cache pela versão anterior não podem ser desserializados pela nova versão. Este problema ocorre mais frequentemente durante grandes atualizações de versões do MSAL.NET ou da Microsoft. Identidade.Web.
Solução
Opção A: Limpar a cache
A solução mais simples é limpar todas as entradas na cache distribuída. Os utilizadores reautenticam-se uma vez, e os tokens subsequentes são escritos no novo formato.
Esvazie a cache Rederis:
redis-cli FLUSHDB
Ou limpar a tabela de cache distribuída do SQL Server:
DELETE FROM [dbo].[TokenCache];
Observação
Limpar a cache faz com que todos os utilizadores ativos voltem a autenticar. Planeie esta operação durante uma janela de manutenção se a sua aplicação servir uma grande base de utilizadores.
Opção B: Lidar com erros de desserialização de forma elegante
Configure o adaptador de cache de modo a tratar as falhas de desserialização como falhas de cache em vez de erros fatais.
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.OnL2CacheFailure = (ex) =>
{
if (ex is JsonException or MsalClientException)
{
logger.LogWarning(ex, "Cache deserialization failed. " +
"Treating as cache miss.");
return true;
}
return false; // Propagate unexpected errors.
};
});
Com esta abordagem, as entradas de cache afetadas são automaticamente substituídas à medida que os utilizadores voltam a autenticar, e não é necessária limpeza manual da cache.
Incompatibilidade de chaves de encriptação entre servidores
Symptom
Erros de desserialização ocorrem em implementações multi-instância, mesmo que a cache distribuída esteja a funcionar. Tokens armazenados em cache por uma instância de servidor não podem ser lidos por outra. Vê os erros json_parse_failed ou IDW10802 nos registos.
Motivo
Quando a encriptação da cache está ativada (options.Encrypt = true), Microsoft. O Identity.Web utiliza o ASP.NET Core Data Protection para encriptar entradas de cache. Por defeito, cada instância de servidor gera as suas próprias chaves de Proteção de Dados, pelo que uma instância não pode desencriptar entradas escritas por outra.
Solução
Configure o ASP.NET Core Data Protection para partilhar chaves de encriptação entre todas as instâncias do servidor.
Opção A: Armazenamento de Blobs do Azure + Azure Key Vault (recomendado para implementações Azure)
using Microsoft.AspNetCore.DataProtection;
using Azure.Identity;
builder.Services.AddDataProtection()
.PersistKeysToAzureBlobStorage(
new Uri("https://yourstorageaccount.blob.core.windows.net/dataprotection/keys.xml"),
new DefaultAzureCredential())
.ProtectKeysWithAzureKeyVault(
new Uri("https://yourkeyvault.vault.azure.net/keys/dataprotection-key"),
new DefaultAzureCredential());
builder.Services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = true;
});
Esta configuração armazena o anel de chaves de Proteção de Dados no Armazenamento de Blobs do Azure e protege as chaves em repouso com o Azure Key Vault. Todas as instâncias de aplicação que acedem ao mesmo blob e chave podem encriptar e desencriptar as entradas de cache umas das outras.
Opção B: Sistema de ficheiros partilhado com proteção de certificados
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(certificate);
Sugestão
Ao rodar o certificado de Proteção de Dados, use UnprotectKeysWithAnyCertificate para incluir tanto os certificados atuais como os anteriores. Isto permite a desencriptação de chaves que estavam protegidas com o certificado antigo durante a janela de rotação.
Crescimento de memória com cache em memória
Symptom
O consumo de memória das aplicações cresce de forma constante ao longo do tempo. Se a aplicação correr num contentor ou plano de Serviço de Aplicações com um limite de memória fixo, acaba por reiniciar ou lançar OutOfMemoryException. A monitorização mostra que a pilha gerida cresce sem recuperação pela coleta de lixo.
Motivo
Usar AddInMemoryTokenCaches() sem limites de tamanho causa um crescimento ilimitado da cache. Esta situação é especialmente problemática em aplicações que servem muitos utilizadores, porque a entrada de token de cada utilizador consome memória indefinidamente.
Por defeito, MemoryCache não impõe um tamanho máximo e não expulsa entradas a menos que esteja definida uma política de validade.
Solução
Opção A: Definir um limite de tamanho e uma expiração deslizante
Configure a cache em memória com políticas de expiração:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddInMemoryTokenCaches();
services.Configure<MsalMemoryTokenCacheOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Com estas definições, as entradas expiram após 12 horas independentemente do acesso, e as entradas inativas durante 2 horas são expulsas mais cedo.
Opção B: Mudar para uma cache distribuída
Para aplicações com muitos utilizadores concorrentes, uma cache em memória não escala. Mude para uma cache distribuída como a Redis:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Uma cache distribuída descarrega memória do processo de aplicação, persiste tokens durante reinícios e suporta implementações multi-instância.
Opção C: Usar a arquitetura híbrida L1/L2
Microsoft. O Identity.Web suporta uma abordagem híbrida que combina uma cache L1 rápida em memória com uma cache L2 distribuída persistente. Configure a cache híbrida L1/L2:
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Com a cache L1/L2, os tokens frequentemente acedidos são servidos a partir da memória (L1) com latência inferior a milissegundos. A cache L2 proporciona persistência e consistência entre instâncias. A cache L1 utiliza expirações curtas para limitar o crescimento da memória.
Prompts repetidos de MFA ou consentimento
Symptom
Os utilizadores são repetidamente solicitados a autenticação multifator (MFA) ou consentimento, mesmo tendo completado estes passos recentemente. A aplicação não consegue encontrar tokens existentes na cache.
Motivo
Este problema ocorre quando a pesquisa de cache de tokens falha em corresponder uma entrada em cache à conta de utilizador atual. As causas comuns incluem:
- A chave de cache difere daquela usada quando o token foi armazenado. Esta situação pode ocorrer se o
HomeAccountIdou o contexto do inquilino mudar. - A aplicação executa múltiplas instâncias atrás de um balanceador de carga com cache em memória, e os pedidos são encaminhados para uma instância que não tem o token do utilizador.
- As reivindicações ou escalas solicitadas mudaram, portanto, o token em cache não atende ao novo requisito.
- A afinidade de sessão não está ativada, fazendo com que os utilizadores sejam encaminhados para diferentes instâncias que não têm os seus tokens em cache.
Passos de diagnóstico
Siga estes passos para identificar porque é que os tokens não são encontrados na cache:
- Verifica o tipo de cache. Se usares
AddInMemoryTokenCaches()numa implementação multi-instância, os tokens armazenados em cache numa instância não estão disponíveis noutra. Muda para uma cache distribuída. - Verifique o identificador da conta. Ative o registo ao nível de depuração e procure o
HomeAccountId. Confirme que o identificador é consistente entre os pedidos. - Inspeciona os telescópios. Confirme que os âmbitos solicitados
GetAccessTokenForUserAsynccorrespondem aos âmbitos originalmente consentidos. Uma incompatibilidade de escopo faz com que a MSAL solicite um novo token. - Revise as políticas de Acesso Condicional. Uma política de Acesso Condicional do Microsoft Entra ID que exige autenticação adicional para recursos específicos causa solicitações adicionais não relacionadas com cache.
Solução
Passo 1: Mudar para cache distribuída
Se a sua aplicação executar múltiplas instâncias, use uma cache distribuída para partilhar tokens entre instâncias:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Passo 2: Verificar objetivos consistentes
Certifique-se de que os escopos que solicita ao adquirir tokens correspondem aos escopos configurados durante a autenticação:
// In authentication setup — initial scopes.
.EnableTokenAcquisitionToCallDownstreamApi(new[] { "User.Read", "Mail.Read" })
// When acquiring a token — use the same scopes.
var token = await tokenAcquisition.GetAccessTokenForUserAsync(
new[] { "User.Read", "Mail.Read" });
Passo 3: Ativar a afinidade da sessão (solução temporária)
Se não conseguires mudar para uma cache distribuída imediatamente, ativa a afinidade de sessão (sessões fixas) no teu balanceador de carga. A afinidade de sessão encaminha os pedidos do utilizador para a mesma instância. Esta abordagem é uma solução temporária com limitações de escalabilidade.
Problemas de desempenho da cache
Symptom
A recuperação de tokens é lenta e as chamadas de API a jusante aumentam a latência. A monitorização mostra tempos médios de resposta elevados para pedidos de aquisição de tokens. A latência não vem do fornecedor de identidade — os tokens são servidos a partir da cache.
Motivo
Problemas de desempenho na cache resultam tipicamente de:
- Alta latência de cache L2. A cache distribuída está sob carga elevada, geograficamente distante da aplicação ou utiliza um nível de serviço subdimensionado.
- Entradas grandes de cache de tokens. Aplicações que armazenam tokens para muitos recursos por utilizador podem produzir grandes entradas de cache serializadas que são lentas a ler e escrever.
- Sem cache L1. Cada aquisição de token vai para a cache distribuída através da rede, mesmo para tokens que são usados frequentemente.
Solução
Passo 1: Ativar a cache L1 em memória
A cache L1 armazena tokens frequentemente acedidos na memória do processo, evitando viagens de rede para L2:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Com esta configuração, os tokens servidos a partir de L1 têm latência submilissegundo. Os tokens que não estão no L1 recuam para a cache distribuída do L2.
Passo 2: Otimizar a camada de cache distribuída
Se a latência da cache L2 for elevada, considere as seguintes ações:
- Escalone a instância do Redis. Mude para um nível superior (por exemplo, de Básico para Padrão ou Premium no Cache do Azure para Redis) para obter maior largura de banda e menor latência.
- Ative a georreplicação. Se a sua aplicação serve utilizadores em várias regiões, utilize a geo-replicação do Cache do Azure para Redis para que a cache fique próxima dos recursos de computação de cada região.
- Rever a configuração da rede. Use integração com Private Link ou VNet para reduzir os saltos de rede entre a aplicação e a cache.
Passo 3: Reduzir o tamanho dos tokens serializados
Se as entradas de cache dos tokens forem grandes, reveja se a aplicação solicita tokens para mais recursos do que o necessário. Cada combinação única de recurso e escopo aumenta o tamanho da entrada do cache. Consolidar chamadas API sempre que possível para reduzir o número de tokens de acesso distintos armazenados em cache por utilizador.
Despejo do cache Redis
Symptom
Os utilizadores são intermitentemente convidados a reautenticar-se sem padrão baseado na expiração do token. A monitorização de Redis mostra que evicted_keys está a aumentar e used_memory está a aproximar-se do limite de maxmemory.
Motivo
Quando o Redis atinge o seu maxmemory limite, remove chaves com base no parâmetro maxmemory-policy. A política padrão (volatile-lru) expulsa as chaves menos usadas recentemente que têm uma expiração. Se a instância Redis for partilhada com dados de outras aplicações, as entradas no cache do token competem por espaço e podem ser expulsas prematuramente.
Solução
Passo 1: Verifique a política de despejos
Verifique a política atual de despejos:
redis-cli CONFIG GET maxmemory-policy
Para caches de tokens, volatile-lru (o padrão) é apropriado porque as entradas de cache de token têm expirações. No entanto, se outros dados sem expirações consomem memória, as entradas do token são despejadas primeiro.
Passo 2: Use uma instância Redis dedicada
Isole a cache de tokens dos outros dados da aplicação utilizando uma instância dedicada do Redis.
{
"ConnectionStrings": {
"RedisTokenCache": "token-cache-redis.redis.cache.windows.net:6380,password=...,ssl=True,abortConnect=False",
"RedisAppData": "app-data-redis.redis.cache.windows.net:6380,password=...,ssl=True,abortConnect=False"
}
}
// Register the token cache Redis instance specifically for distributed caching.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("RedisTokenCache");
});
Passo 3: Aumentar o limite de memória do Redis
Se uma instância dedicada não for viável, aumenta a maxmemory definição. No Cache do Azure para Redis, escala para um nível superior ou aumenta o tamanho da cache.
Passo 4: Definir expirações apropriadas para entradas de cache
Defina expirações razoáveis para que entradas obsoletas sejam removidas antes que a memória se esgote:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(12);
options.SlidingExpiration = TimeSpan.FromHours(2);
});
Crescimento de tabelas de cache distribuídas em SQL
Symptom
A tabela de cache distribuída SQL cresce continuamente, consumindo espaço em disco. As consultas à base de dados contra a tabela de cache abrandam com o tempo, e podes ver avisos sobre o tamanho da tabela ou limites de armazenamento.
Motivo
A cache distribuída SQL Server (Microsoft.Extensions.Caching.SqlServer) não remove automaticamente entradas expiradas. Entradas expiradas permanecem até serem explicitamente purgadas, causando crescimento ilimitado das tabelas, desempenho degradado da consulta e consumo de armazenamento.
Solução
Passo 1: Marque um trabalho de limpeza recorrente
Crie um trabalho ou tarefa agendada no SQL Server Agent para remover periodicamente entradas expiradas:
-- Delete expired entries from the SQL distributed cache table.
-- Schedule this query to run every 30 minutes.
DELETE FROM [dbo].[TokenCache]
WHERE ExpiresAtTime < GETUTCDATE();
Sugestão
No Base de Dados SQL do Azure, onde o SQL Server Agent não está disponível, utilize o Automatização do Azure, Funções do Azure com um acionador de temporizador, ou Elastic Jobs para agendar a limpeza.
Passo 2: Adicione um índice para uma limpeza eficiente
Se a tabela de cache ainda não tiver um índice na coluna de expiração, adicione um para acelerar a operação de eliminação:
CREATE NONCLUSTERED INDEX IX_TokenCache_ExpiresAtTime
ON [dbo].[TokenCache] (ExpiresAtTime);
Passo 3: Monitorizar o tamanho da mesa
Adicione monitorização para acompanhar o número de linhas e o tamanho da tabela ao longo do tempo:
SELECT
COUNT(*) AS TotalEntries,
COUNT(CASE WHEN ExpiresAtTime < GETUTCDATE() THEN 1 END) AS ExpiredEntries,
COUNT(CASE WHEN ExpiresAtTime >= GETUTCDATE() THEN 1 END) AS ActiveEntries
FROM [dbo].[TokenCache];
Passo 4: Considera mudar para Redis
Se gerenciar a limpeza do cache SQL se tornar um fardo, mude para o Redis, que trata automaticamente da expiração através do seu mecanismo TTL automático.
// Replace SQL distributed cache with Redis.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
Sugestões gerais de resolução de problemas
Use estas dicas quando o seu problema não corresponde a um cenário específico neste artigo.
Verifique se a cache está a ser usada
Adicione registo temporário para confirmar que os tokens são lidos e gravados na cache:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.Encrypt = false; // Disable encryption temporarily for debugging only.
options.OnL2CacheFailure = (ex) =>
{
logger.LogError(ex, "L2 cache operation failed.");
return true;
};
});
Verifique se há múltiplos registos de cache
Se existirem múltiplas chamadas para AddInMemoryTokenCaches() ou AddDistributedTokenCaches() no código de inicialização, o último registo prevalece. Verifique se apenas um tipo de cache está registado.
Revise a vida útil do token
Os tokens de acesso têm uma vida útil finita (tipicamente 60–90 minutos). Se os utilizadores reportarem reautenticação após este período, o comportamento é esperado e não um problema de cache. Os tokens de atualização obtêm novos tokens de acesso silenciosamente e são armazenados na cache. Se o token de atualização estiver em falta ou expirado, o utilizador deve voltar a autenticar.
Teste com uma cache limpa
Ao diagnosticar problemas, limpe a cache para excluir entradas corrompidas ou obsoletas:
- Cache em memória: Reinicie a aplicação.
-
Redis: Executa
FLUSHDBna base de dados de cache. - SQL Server: Apagar todas as linhas da tabela de cache.
Cache de token vazio após reinício da aplicação
Symptom
Os utilizadores devem reautenticar-se após cada reinício ou reimplementação da aplicação. A cache distribuída parece vazia ou os tokens não são preservados.
Motivo
Este problema ocorre tipicamente quando se utiliza uma cache em memória (AddInMemoryTokenCaches()) ou a cache de memória distribuída não persistente (AddDistributedMemoryCache()) em produção. Nenhuma das opções mantém os tokens após os reinícios da aplicação.
AddDistributedMemoryCache() regista uma IDistributedCache implementação que armazena dados na memória. Apesar do nome "distribuído", este não armazena dados fora do sistema e destina-se apenas ao desenvolvimento e testes.
Solução
Mudar para uma cache distribuída persistente:
// Register a persistent cache (Redis example).
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = builder.Configuration.GetConnectionString("Redis");
options.InstanceName = "MyApp_";
});
// Use distributed token caches instead of in-memory.
builder.Services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(builder.Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Advertência
Não confunda AddDistributedMemoryCache() com uma cache distribuída persistente. Use AddStackExchangeRedisCache() (Redis), AddDistributedSqlServerCache() (SQL Server), ou outra implementação persistente IDistributedCache para cargas de trabalho de produção.