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 oferece soluções para o erro "Nenhuma conta ou dica de logon foi passada para o AcquireTokenSilent" que ocorre em um aplicativo Web usando a MSAL (Biblioteca de Autenticação da Microsoft) ou o Microsoft Identity Web.
Sintomas
Suponha que seus aplicativos Web autentiquem usuários usando MSAL ou Microsoft Identity Web e não usem caches de token persistentes. Quando o MSAL tenta extrair uma conta de usuário e adquirir um token de forma discreta de seu armazenamento de token, a seguinte mensagem de erro é exibida:
Nenhuma conta ou dica de logon foi passada para o AcquireTokenSilent
Motivo
Esse problema ocorre porque a MSAL procura uma conta que não existe mais no cache de token com base em um cookie de autenticação existente. O cookie de autenticação é criado somente após uma entrada interativa e contém informações sobre o usuário. Esse problema ocorre nos seguintes cenários:
- O aplicativo Web foi reiniciado.
- A memória é liberada devido ao uso elevado de memória ou após um período de inatividade determinado.
- A MSAL tem um limite de tamanho de cache padrão que remove automaticamente entradas mais antigas.
Solução 1 (recomendado): Implementar um cache de token persistente
Você pode implementar um cache de token persistente em um local durável, como o SQL Server ou o armazenamento baseado em arquivo. Um cache de token persistente garante que os tokens sejam retidos mesmo quando o aplicativo for reiniciado ou a memória for limpa. Para obter mais informações sobre como implementar um cache de token persistente personalizado, consulte a serialização do cache de token.
Solução 2: Rejeitar o cookie de autenticação
Você pode implementar um evento de autenticação de cookie para validar se o usuário conectado atualmente está presente no cache de token MSAL. Se o usuário não estiver presente, rejeite o cookie de autenticação e force o usuário atual a entrar novamente.
Para aplicativos Web ASP.NET usando MSAL
Criar um evento de autenticação de cookie:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
Provider = new CookieAuthenticationProvider()
{
OnValidateIdentity = async context =>
{
IConfidentialClientApplication clientApp = MsalAppBuilder.BuildConfidentialClientApplication();
var signedInUserIdentity = new ClaimsPrincipal(context.Identity);
if (await clientApp.GetAccountAsync(signedInUserIdentity.GetAccountId()) == null)
{
context.RejectIdentity();
}
}
}
});
Observação
Para implementar um evento de autenticação de cookie, o aplicativo Web deve instalar as seguintes classes auxiliares e o Microsoft.Identity.Web.TokenCache
pacote NuGet:
MsalAppBuilder.cs
AuthenticationConfig.cs
Para aplicações Web ASP.NET Core usando MSAL
Criar um evento de autenticação de cookie personalizado:
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.Extensions.DependencyInjection; using Microsoft.Identity.Client; using System.Threading.Tasks; using System.Security.Claims; namespace SampleApp.Services { internal class RejectSessionCookieWhenAccountNotInCacheEvents : CookieAuthenticationEvents { public async override Task ValidatePrincipal(CookieValidatePrincipalContext context) { var msalInstance = context.HttpContext.RequestServices.GetRequiredService(); IConfidentialClientApplication msalClient = msalInstance.GetClient(); var accounts = await msalClient.GetAccountsAsync(); var account = await msalClient.GetAccountAsync(accounts.FirstOrDefault()); if (account == null) { context.RejectPrincipal(); } await base.OnValidatePrincipal(context); } } }
Registre o evento de autenticação de cookie personalizado:
Services.Configure<CookieAuthenticationOptions>(cookieScheme, options=>options.Events=new RejectSessionCookieWhenAccountNotInCacheEvents());
Para aplicativos Web usando o Microsoft Identity Web
O Microsoft Identity Web fornece mecanismos internos para gerenciar caches de token. Para obter mais informações, consulte Gerenciando o consentimento incremental e o acesso condicional. Se este documento não ajudar você a resolver o problema, você poderá limpar manualmente o cookie de autenticação usando um evento de autenticação de cookie personalizado:
Criar um evento de autenticação de cookie personalizado:
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.Extensions.DependencyInjection; using Microsoft.Identity.Client; using Microsoft.Identity.Web; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace SampleApp.Services { internal class RejectSessionCookieWhenAccountNotInCacheEvents : CookieAuthenticationEvents { public async override Task ValidatePrincipal(CookieValidatePrincipalContext context) { try { var tokenAcquisition = context.HttpContext.RequestServices.GetRequiredService(); string token = await tokenAcquisition.GetAccessTokenForUserAsync( scopes: new[] { "profile" }, user: context.Principal); } catch (MicrosoftIdentityWebChallengeUserException ex) when (AccountDoesNotExistInTokenCache(ex)) { context.RejectPrincipal(); } } /// <summary> /// Is the exception due to no account in the token cache? /// </summary> /// <param name="ex">Exception thrown by <see cref="ITokenAcquisition"/>.GetTokenForXX methods.</param> /// <returns>A boolean indicating if the exception relates to the absence of an account in the cache.</returns> private static bool AccountDoesNotExistInTokenCache(MicrosoftIdentityWebChallengeUserException ex) { return ex.InnerException is MsalUiRequiredException && (ex.InnerException as MsalUiRequiredException).ErrorCode == "user_null"; } } }
Registre o evento de autenticação de cookie personalizado:
// Add Microsoft Identity Web services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme) .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd")) .EnableTokenAcquisitionToCallDownstreamApi(initialScopes) .AddMicrosoftGraph(Configuration.GetSection("GraphBeta")) .AddInMemoryTokenCaches(); // Register the Custom Cookie Authentication event Services.Configure<CookieAuthenticationOptions>(cookieScheme, options=>options.Events=new RejectSessionCookieWhenAccountNotInCacheEvents());
Entre em contato conosco para obter ajuda
Se você tiver dúvidas ou precisar de ajuda, crie uma solicitação de suporte ou peça ajuda à comunidade de suporte do Azure. Você também pode enviar comentários sobre o produto para a comunidade de comentários do Azure.