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.
Este artigo ajuda você a diagnosticar e resolver problemas de cache de token em Microsoft. Identity.Web. Problemas de cache de token podem causar falhas de autenticação, desempenho degradado ou prompts de entrada inesperados. Para obter uma visão geral de como o cache de token funciona em Microsoft. Identity.Web, consulte Token cache overview.
Pré-requisitos
Antes de solucionar problemas, confirme o seguinte:
- Você está usando uma versão suportada do Microsoft. Identity.Web.
- Seu aplicativo tem o cache de token configurado em
Program.csouStartup.cs. - Você tem acesso aos logs de aplicativos e, se aplicável, à infraestrutura de cache distribuído.
Habilitar registro e diagnóstico do cache de token
Habilite o log detalhado como sua primeira etapa de diagnóstico. Microsoft.Identity.Web usa a infraestrutura de logging do ASP.NET Core e emite eventos por meio da Biblioteca do Microsoft Authenticator (MSAL).
Habilitar o log do MSAL
Defina o nível de log das bibliotecas de identidade para Debug em appsettings.json.
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Identity.Web": "Debug",
"Microsoft.IdentityModel": "Debug"
}
}
}
Inscrever-se nos eventos de cache do MSAL
Assine eventos de notificação de cache de token MSAL para acompanhar ocorrências de cache, erros 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;
};
});
Monitorar métricas de cache
Para monitoramento de produção, acompanhe estas principais métricas:
- Taxa de ocorrência de cache – uma taxa de ocorrência baixa indica que os tokens não estão sendo recuperados do cache.
- Latência de cache L2 – alta latência sugere um problema de desempenho ou conectividade de cache distribuído.
- Erros de serialização de cache – erros durante a leitura ou gravação indicam corrupção ou incompatibilidade de versão.
- Consumo de memória – o crescimento sustentado pode indicar ausência de políticas de expulsão.
Falhas nas conexões do cache distribuído (L2)
Sintoma
Os logs de aplicativo mostram erros de tempo limite de conexão ou falhas de autenticação intermitente. Os usuários enfrentam atrasos de entrada e você vê exceções como:
Microsoft.Extensions.Caching.StackExchangeRedis.RedisCache:
StackExchange.Redis.RedisConnectionException:
No connection is active/available to service this operation.
Em relação ao 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 repositório de backup de cache distribuído (Redis ou SQL Server) é inacessível. As causas mais comuns incluem:
- String de conexão incorreta ou credenciais de acesso expiradas.
- Regras de firewall de rede bloqueando a conexão do host do aplicativo.
- O serviço de cache está inativo ou passando por manutenção.
- Incompatibilidade de configuração de SSL/TLS entre o cliente e o servidor de cache.
Etapas de diagnóstico
Siga estas etapas para identificar a falha de conexão:
- Verifique a conectividade. No host do aplicativo, teste a conexão com Redis ou SQL Server usando
Test-NetConnection(PowerShell) ouredis-cli. - Verifique a string de conexão. Confirme se o cadeia de conexão corresponde ao nome do host, à porta e às credenciais do servidor de cache.
- Examine as regras de firewall. Em Azure, verifique se o serviço de aplicativo ou a rede virtual pode acessar o recurso de cache.
- Verifique a integridade do serviço. No portal do Azure, examine a integridade e as métricas de sua instância de banco de dados Cache do Azure para Redis ou SQL.
Solução
Etapa 1: corrija o *cadeia de conexão*
Verifique a cadeia de conexão em 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. Essa configuração permite que o aplicativo se reconecte automaticamente após falhas transitórias de conexão em vez de gerar imediatamente.
Etapa 2: Configurar repetição e resiliência
Configure o OnL2CacheFailure callback para que o aplicativo seja degradado de forma elegante quando o cache distribuído 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);
});
Etapa 3: Abrir regras de firewall
Se o aplicativo for executado em Serviço de Aplicativo do Azure e o cache estiver em uma rede virtual, adicione os endereços IP de saída do Serviço de Aplicativo à lista de permissões de firewall de cache.
Erros de desserialização de cache
Sintoma
Depois de atualizar Microsoft.Identity.Web ou o MSAL.NET, o aplicativo lança exceções de desserialização ao ler do cache distribuído. Os usuários devem entrar novamente e você verá 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 do cache de token foi alterado entre as versões da biblioteca. Tokens armazenados em cache pela versão anterior não podem ser desserializados pela nova versão. Esse problema ocorre com mais frequência durante atualizações de versão principais de MSAL.NET ou Microsoft. Identity.Web.
Solução
Opção A: Limpar o cache
A correção mais simples é limpar todas as entradas no cache distribuído. Os usuários reautenticam uma vez e os tokens subsequentes são gravados no novo formato.
Libere o cache Redis:
redis-cli FLUSHDB
Ou limpe a tabela de cache distribuída do SQL Server:
DELETE FROM [dbo].[TokenCache];
Observação
Limpar o cache faz com que todos os usuários ativos se reautentiquem. Planeje essa operação durante uma janela de manutenção se o aplicativo atender a uma grande base de usuários.
Opção B: Manipular erros de desserialização de forma elegante
Configure o adaptador de cache para tratar falhas de desserialização como erros 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 essa abordagem, as entradas de cache afetadas são automaticamente substituídas à medida que os usuários se autenticam novamente e nenhuma liberação manual de cache é necessária.
Incompatibilidade de chave de criptografia entre servidores
Sintoma
Erros de desserialização ocorrem em implantações de várias instâncias, embora o cache distribuído esteja funcionando. Tokens armazenados em cache por uma instância de servidor não podem ser lidos por outra. Você vê json_parse_failed ou IDW10802 erros nos registros.
Motivo
Quando a criptografia de cache estiver habilitada (options.Encrypt = true), Microsoft. O Identity.Web usa ASP.NET Core Data Protection para criptografar entradas de cache. Por padrão, cada instância de servidor gera suas próprias chaves de Proteção de Dados, de modo que uma instância não pode descriptografar entradas gravadas por outra.
Solução
Configure o ASP.NET Core para proteção de dados e compartilhamento de chaves de criptografia em todas as instâncias do servidor.
Option A: Armazenamento de Blobs do Azure + Azure Key Vault (recomendado para implantações de 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;
});
Essa configuração armazena o anel de chaves da Proteção de Dados em Armazenamento de Blobs do Azure e protege as chaves em repouso com Azure Key Vault. Todas as instâncias de aplicativo que acessam o mesmo blob e chave podem criptografar e descriptografar as entradas de cache umas das outras.
Opção B: sistema de arquivos compartilhado com proteção de certificado
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\keys"))
.ProtectKeysWithCertificate(certificate);
Dica
Ao girar o certificado de Proteção de Dados, use UnprotectKeysWithAnyCertificate para incluir os certificados atuais e anteriores. Isso permite a descriptografia de chaves que foram protegidas com o certificado antigo durante a janela de rotação.
Crescimento de memória com cache em memória
Sintoma
O consumo de memória do aplicativo cresce constantemente ao longo do tempo. Se o aplicativo for executado em um contêiner ou em um plano do Serviço de Aplicações com um limite de memória fixo, ele eventualmente reiniciará ou gerará OutOfMemoryException. O monitoramento mostra o heap gerenciado crescendo sem recuperação pela coleta de lixo.
Motivo
Usar AddInMemoryTokenCaches() sem limites de tamanho causa um crescimento ilimitado do cache. Essa situação é especialmente problemática em aplicativos que atendem a muitos usuários, pois a entrada de token de cada usuário consome memória indefinidamente.
Por padrão, MemoryCache não impõe um tamanho máximo e não remove entradas, a menos que uma política de expiração seja definida.
Solução
Opção A: Definir um limite de tamanho e expiração deslizante
Configure o cache na 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 essas configurações, as entradas expiram após 12 horas, independentemente do acesso, e as entradas ociosas por 2 horas são removidas anteriormente.
Opção B: alternar para um cache distribuído
Para aplicativos com muitos usuários simultâneos, um cache na memória não escala bem. Alterne para um cache distribuído, como Redis:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Um cache distribuído reduz a carga de memória do processo do aplicativo, mantém tokens persistentes durante reinicializações e suporta implantações de múltiplas instâncias.
Opção C: usar a arquitetura híbrida L1/L2
Microsoft. O Identity.Web dá suporte a uma abordagem híbrida que combina um cache L1 rápido na memória com um cache L2 distribuído persistente. Configure o cache híbrido 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 o cache L1/L2, os tokens acessados com frequência são servidos do cache em memória L1 com latência inferior a milissegundos. O cache L2 fornece persistência e consistência entre instâncias. O cache L1 usa expirações curtas para limitar o crescimento da memória.
Prompts de consentimento ou MFA repetidos
Sintoma
Os usuários são solicitados repetidamente para autenticação multifator (MFA) ou consentimento, mesmo que tenham concluído essas etapas recentemente. O aplicativo não pode encontrar tokens existentes no cache.
Motivo
Esse problema ocorre quando a busca no cache de tokens falha em encontrar uma entrada armazenada que corresponda à conta de usuário atual. As causas mais comuns incluem:
- A chave de cache difere da usada quando o token foi armazenado. Essa situação pode ocorrer se o
HomeAccountIdou o contexto do locatário for alterado. - O aplicativo executa várias instâncias atrás de um balanceador de carga com cache na memória e solicita a rota para uma instância que não tem o token do usuário.
- As declarações ou escopos solicitados foram alterados, para que o token armazenado em cache não atenda ao novo requisito.
- A afinidade de sessão não está habilitada, portanto, os usuários são direcionados para instâncias diferentes que não têm os tokens armazenados em cache.
Etapas de diagnóstico
Siga estas etapas para identificar por que os tokens não são encontrados no cache:
- Verifique o tipo de cache. Se você usar
AddInMemoryTokenCaches()em uma implantação de várias instâncias, os tokens armazenados em cache em uma instância não estão disponíveis em outra. Alterne para um cache distribuído. - Verifique o identificador da conta. Habilite o logging no nível de depuração e pesquise o
HomeAccountId. Confirme se o identificador é consistente entre solicitações. - Inspecione os escopos. Confirme se os escopos solicitados pela
GetAccessTokenForUserAsynccorrespondem aos escopos originalmente consentidos. Uma incompatibilidade de escopo faz com que a MSAL solicite um novo token. - Examine as políticas de Acesso Condicional. Uma política de acesso condicional do Microsoft Entra ID que requer autenticação de nível superior para recursos específicos gera solicitações adicionais não relacionadas ao cache.
Solução
Etapa 1: alternar para o cache distribuído
Se o aplicativo executar várias instâncias, use um cache distribuído para compartilhar tokens entre instâncias:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApp(Configuration)
.EnableTokenAcquisitionToCallDownstreamApi()
.AddDistributedTokenCaches();
Etapa 2: verificar escopos consistentes
Verifique se os escopos solicitados 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" });
Etapa 3: Habilitar afinidade de sessão (solução alternativa temporária)
Se você não conseguir alternar para um cache distribuído imediatamente, habilite a afinidade de sessão (sessões persistentes) no balanceador de carga. A afinidade de sessão roteia as solicitações de um usuário para a mesma instância. Essa abordagem é uma solução alternativa temporária com limitações de escalabilidade.
Problemas de desempenho de cache
Sintoma
A recuperação de token é lenta e as chamadas à API downstream aumentaram a latência. O monitoramento mostra altos tempos médios de resposta para solicitações de aquisição de token. A latência não é do provedor de identidade—os tokens são servidos a partir do cache.
Motivo
Problemas de desempenho de cache normalmente resultam de:
- Alta latência de cache L2. O cache distribuído está sob carga pesada, geograficamente distante do aplicativo ou usando uma camada de serviço subdimensionada.
- Entradas grandes de cache de token. Aplicativos que armazenam tokens em cache para muitos recursos por usuário podem produzir entradas de cache serializadas grandes que são lentas para ler e gravar.
- Sem cache L1. Cada aquisição de token vai para o cache distribuído pela rede, mesmo para tokens usados com frequência.
Solução
Etapa 1: Habilitar o cache na memória L1
O cache L1 armazena tokens acessados com frequência na memória do processo, evitando viagens de ida e volta de rede para L2:
services.Configure<MsalDistributedTokenCacheAdapterOptions>(options =>
{
options.L1CacheOptions = new MsalMemoryTokenCacheOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(5),
SlidingExpiration = TimeSpan.FromMinutes(2)
};
});
Com essa configuração, a latência dos tokens servidos a partir do L1 é de sub-milissegundos. Os tokens que não estão em L1 retornam ao cache distribuído L2.
Etapa 2: Otimizar a camada de cache distribuída
Se a latência de cache L2 for alta, considere as seguintes ações:
- Escalar verticalmente a instância do Redis. Mova para uma camada mais alta (por exemplo, de Basic para Standard ou Premium em Cache do Azure para Redis) para obter mais taxa de transferência e menor latência.
- Habilitar a replicação geográfica. Se o aplicativo atender usuários em várias regiões, use o Cache do Azure para Redis para replicação geográfica, a fim de que o cache fique próximo aos recursos de computação de cada região.
- Examine a configuração de rede. Use Link Privado ou integração de VNet para reduzir os saltos de rede entre o aplicativo e o cache.
Etapa 3: reduzir o tamanho do token serializado
Se as entradas de cache de token forem grandes, examine se o aplicativo solicita tokens para mais recursos do que o necessário. Cada combinação de escopo e recursos exclusivos adiciona ao tamanho da entrada de cache. Consolide as chamadas à API sempre que possível para reduzir o número de tokens de acesso distintos armazenados em cache por usuário.
Expulsão do cache Redis
Sintoma
Os usuários são solicitados intermitentemente a se reautenticar sem nenhum padrão com base na expiração do token. O monitoramento do Redis mostra o evicted_keys aumentando e o used_memory se aproximando do maxmemory limite.
Motivo
Quando o Redis atinge seu maxmemory limite, ele descarta as chaves com base na configuração maxmemory-policy. A política padrão (volatile-lru) remove as chaves menos usadas recentemente que têm uma expiração. Se a instância do Redis for compartilhada com outros dados do aplicativo, as entradas de cache de token competirão por espaço e poderão ser removidas prematuramente.
Solução
Etapa 1: Verificar a política de remoção
Verifique a política de remoção atual:
redis-cli CONFIG GET maxmemory-policy
Para caches de token, 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 consumirem memória, as entradas de token serão removidas primeiro.
Etapa 2: usar uma instância dedicada do Redis
Isole o cache de token dos outros dados do aplicativo usando uma instância do Redis dedicada.
{
"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");
});
Etapa 3: Aumentar o limite de memória do Redis
Se uma instância dedicada não for viável, aumente a maxmemory configuração. Em Cache do Azure para Redis, escalone para um nível superior ou aumente o tamanho do cache.
Etapa 4: Definir expirações de entrada de cache apropriadas
Defina expirações razoáveis para que as 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 da tabela de cache distribuída no SQL
Sintoma
A tabela de cache distribuído do SQL cresce continuamente, consumindo espaço em disco. Consultas de banco de dados na tabela de cache são lentas ao longo do tempo e você pode ver avisos sobre o tamanho da tabela ou os limites de armazenamento.
Motivo
O cache distribuído SQL Server (Microsoft.Extensions.Caching.SqlServer) não remove automaticamente as entradas expiradas. As entradas expiradas permanecem até serem explicitamente removidas, causando crescimento ilimitado da tabela, desempenho degradado das consultas e consumo de armazenamento.
Solução
Etapa 1: Configurar um trabalho de limpeza recorrente
Crie um trabalho SQL Server Agent ou uma tarefa agendada para remover periodicamente as 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();
Dica
Em Banco de Dados SQL do Azure, em que SQL Server Agent não está disponível, use Automação do Azure, Azure Functions com um gatilho de temporizador ou Jobs Elásticos para agendar a limpeza.
Etapa 2: Adicionar um índice para 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 exclusão:
CREATE NONCLUSTERED INDEX IX_TokenCache_ExpiresAtTime
ON [dbo].[TokenCache] (ExpiresAtTime);
Etapa 3: Monitorar o tamanho da tabela
Adicione monitoramento para acompanhar a contagem 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];
Etapa 4: Considere mudar para Redis
Se o gerenciamento da limpeza de cache do SQL for oneroso, mude para o Redis, que manipula a expiração automaticamente por meio de seu mecanismo TTL interno.
// Replace SQL distributed cache with Redis.
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = Configuration.GetConnectionString("Redis");
});
Dicas de solução de problemas gerais
Use essas dicas quando o problema não corresponder a um cenário específico neste artigo.
Verifique se o cache está sendo usado
Adicione log temporário para confirmar se os tokens são lidos e gravados no 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;
};
});
Verificar se há vários registros de cache
Se várias chamadas para AddInMemoryTokenCaches() ou AddDistributedTokenCaches() existirem no código de inicialização, o último registro ganhará. Verifique se apenas um tipo de cache está registrado.
Examinar o tempo de vida do token
Os tokens de acesso têm um tempo de vida finito (normalmente de 60 a 90 minutos). Se os usuários relatarem reautenticação após esse período, o comportamento será esperado em vez de um problema de cache. Os tokens de atualização obtêm novos tokens de acesso silenciosamente e são armazenados no cache. Se o token de atualização estiver ausente ou expirado, o usuário deverá autenticar novamente.
Teste com um cache limpo
Ao diagnosticar problemas, desmarque o cache para excluir entradas corrompidas ou obsoletas:
- Cache na memória: Reinicie o aplicativo.
-
Redis: Execute
FLUSHDBno banco de dados de cache. - SQL Server: Excluir todas as linhas da tabela de cache.
Cache de token vazio após a reinicialização do aplicativo
Sintoma
Os usuários devem reautenticar após a reinicialização ou reimplantação de cada aplicativo. O cache distribuído aparece vazio ou os tokens não são persistidos.
Motivo
Esse problema normalmente ocorre quando você usa um cache na memória (AddInMemoryTokenCaches()) ou o cache de memória distribuída não persistente (AddDistributedMemoryCache()) em produção. Nenhuma opção mantém tokens entre reinicializações do aplicativo.
AddDistributedMemoryCache() registra uma implementação IDistributedCache que armazena dados na memória. Apesar do nome "distribuído", ele não mantém dados externamente e é destinado apenas para desenvolvimento e teste.
Solução
Mude para um cache distribuído 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();
Aviso
Não confunda AddDistributedMemoryCache() com um cache distribuído persistente. Use AddStackExchangeRedisCache() (Redis), AddDistributedSqlServerCache() (SQL Server) ou outra implementação persistente IDistributedCache para cargas de trabalho de produção.