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 fornece uma visão geral dos diferentes tipos de erros e recomendações para lidar com erros comuns de entrada.
Noções básicas sobre o tratamento de erros do MSAL
As exceções no Biblioteca do Microsoft Authenticator (MSAL) destinam-se aos desenvolvedores de aplicativos a solucionar problemas, não para exibição para usuários finais. As mensagens de exceção não são localizadas.
Ao processar exceções e erros, você pode usar o tipo de exceção em si e o código de erro para distinguir entre exceções. Para obter uma lista de códigos de erro, consulte Microsoft Entra códigos de erro de autenticação e autorização.
Durante a experiência de entrada, você pode encontrar erros sobre consentimentos, MFA (Acesso Condicional, Gerenciamento de Dispositivos, restrições baseadas em local), emissão e resgate de token e propriedades do usuário.
A seção a seguir fornece mais detalhes sobre o tratamento de erros para seu aplicativo.
Tratamento de erros no MSAL.NET
Tipos de exceção
MsalClientException é gerado quando a própria biblioteca detecta um estado de erro, como uma configuração incorreta.
MsalServiceException é lançada quando o provedor de identidade (Microsoft Entra ID) retorna um erro. É uma tradução do erro do servidor.
MsalUIRequiredException é um tipo de MsalServiceException e indica que a interação do usuário é necessária. Por exemplo, quando a MFA (autenticação multifator) é necessária ou quando o usuário altera sua senha e um token não pode ser adquirido silenciosamente.
Exceções de processamento
Ao processar exceções .NET, você pode usar o tipo de exceção em si e o membro ErrorCode para distinguir entre exceções.
ErrorCode os valores são constantes do tipo MsalError.
Você também pode dar uma olhada nos campos de MsalClientException, MsalServiceException e MsalUIRequiredException.
Se MsalServiceException for gerado, tente códigos de erro de autenticação e autorização para ver se o código está listado lá.
Se MsalUIRequiredException for gerado, é uma indicação de que um fluxo interativo precisa acontecer para que o usuário resolva o problema. Em aplicativos cliente públicos, como desktop e aplicativo móvel, isso é resolvido chamando AcquireTokenInteractive, que exibe um navegador. Em aplicativos cliente confidenciais, os aplicativos Web devem redirecionar o usuário para a página de autorização e as APIs Web devem retornar um código de status HTTP e um cabeçalho que indica a falha de autenticação (401 Não autorizado e um cabeçalho WWW-Authenticate).
Exceções comuns de .NET
Aqui estão as exceções comuns que podem ser lançadas e algumas possíveis mitigações:
| Exceção | Código do erro | Atenuação |
|---|---|---|
| MsalUiRequiredException | AADSTS65001: o usuário ou administrador não consentiu em usar o aplicativo com a ID '{appId}' chamada '{appName}'. Envie uma solicitação de autorização interativa para esse usuário e recurso. | Obtenha o consentimento do usuário primeiro. Se você não estiver usando o .NET Core (que não tem interface Web), chame (apenas uma vez) AcquireTokenInteractive. Se você estiver usando o .NET Core ou não quiser fazer um AcquireTokenInteractive, o usuário poderá acessar uma URL para dar seu consentimento: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read. para chamar AcquireTokenInteractive: app.AcquireTokenInteractive(scopes).WithAccount(account).WithClaims(ex.Claims).ExecuteAsync(); |
| MsalUiRequiredException | AADSTS50079: o usuário deve usar a MFA (autenticação multifator). | Não há atenuação. Se o MFA estiver configurado para o seu locatário e o Microsoft Entra ID decidir aplicá-lo, recorra a um fluxo interativo, como AcquireTokenInteractive. |
| MsalServiceException | AADSTS90010: não há suporte para o tipo de concessão nos pontos de extremidade /common ou /consumers . Use o endpoint /organizations ou o endpoint específico do locatário. Você usou /common. | Conforme explicado na mensagem do Microsoft Entra ID, a autoridade precisa ter um locatário ou, caso contrário, /organizations. |
| MsalServiceException | AADSTS70002: o corpo da solicitação deve conter o seguinte parâmetro: client_secret or client_assertion. |
Essa exceção poderá ser gerada se o aplicativo não tiver sido registrado como um aplicativo cliente público no Microsoft Entra ID. No centro de administração do Microsoft Entra, edite o manifesto do aplicativo e defina allowPublicClient como true. |
| MsalClientException |
unknown_user Message: não foi possível identificar o usuário conectado |
A biblioteca não pôde consultar o usuário atualmente conectado ao Windows ou esse usuário não ingressou no Active Directory nem no Microsoft Entra (não há suporte para usuários associados ao local de trabalho). Mitigação: Implemente sua própria lógica para obter o nome de usuário (por exemplo, john@contoso.com) e use a forma AcquireTokenByIntegratedWindowsAuth, que recebe o nome de usuário. |
| MsalClientException | autenticação integrada do Windows não é compatível com usuário gerenciado | Esse método se baseia em um protocolo exposto por Active Directory (AD). Se um usuário tiver sido criado em Microsoft Entra ID sem suporte do AD (usuário "gerenciado"), esse método falhará. Os usuários criados no AD e apoiados por Microsoft Entra ID (usuários "federados") podem se beneficiar desse método não interativo de autenticação. Mitigação: use a autenticação interativa. |
MsalUiRequiredException
Um dos códigos de status comuns retornados de MSAL.NET ao chamar AcquireTokenSilent() é MsalError.InvalidGrantError. Esse código de status significa que o aplicativo deve chamar a biblioteca de autenticação novamente, mas no modo interativo (AcquireTokenInteractive ou AcquireTokenByDeviceCodeFlow para aplicativos cliente públicos, tem um desafio em aplicativos Web). Isso ocorre porque a interação adicional do usuário é necessária antes que o token de autenticação possa ser emitido.
Na maioria das vezes, quando AcquireTokenSilent falha, é porque o cache de token não tem tokens correspondentes à sua solicitação. Os tokens de acesso expiram em 1 hora e AcquireTokenSilent tentam buscar um novo com base em um token de atualização (em termos OAuth2, esse é o fluxo "Atualizar Token"). Esse fluxo também pode falhar por vários motivos, por exemplo, se um administrador de locatários configurar políticas de entrada mais rigorosas.
A interação visa fazer com que o usuário faça uma ação. Algumas dessas condições são fáceis de serem resolvidas pelos usuários (por exemplo, aceitem termos de uso com um único clique) e outras não podem ser resolvidas com a configuração atual (por exemplo, o computador em questão precisa se conectar a uma rede corporativa específica). Alguns ajudam o usuário a configurar a autenticação multifator ou a instalar Microsoft Authenticator em seu dispositivo.
MsalUiRequiredException enumeração de classes
O MSAL expõe um campo Classification, que você pode ler para oferecer uma experiência do usuário melhor. Por exemplo, para informar ao usuário que sua senha expirou ou que ele precisa fornecer consentimento para usar alguns recursos. Os valores com suporte fazem parte da UiRequiredExceptionClassification enumeração:
| Classification | Meaning | Tratamento recomendado |
|---|---|---|
| BasicAction | A condição pode ser resolvida pela interação do usuário durante o fluxo de autenticação interativa. | Chame AcquireTokenInteractively(). |
| Ação adicional | A condição pode ser resolvida por interação corretiva adicional com o sistema, fora do fluxo de autenticação interativa. | Chame AcquireTokenInteractively() para mostrar uma mensagem que explica a ação corretiva. O aplicativo chamador pode optar por ocultar fluxos que exigem additional_action se for improvável que o usuário conclua a ação de correção. |
| Somente mensagem | A condição não pode ser resolvida no momento. Iniciar o fluxo de autenticação interativa mostrará uma mensagem explicando a condição. | Chame AcquireTokenInteractively() para mostrar uma mensagem que explica a condição. AcquireTokenInteractively() retornará o erro UserCanceled depois que o usuário ler a mensagem e fechar a janela. O aplicativo chamador pode optar por ocultar fluxos que resultem em message_only se for improvável que a mensagem beneficie o usuário. |
| Consentimento necessário | O consentimento do usuário está ausente ou foi revogado. | Chame AcquireTokenInteractively() para que o usuário dê consentimento. |
| Senha do usuário expirada | A senha do usuário expirou. | Chame AcquireTokenInteractively() para que o usuário possa redefinir sua senha. |
| PromptNeverFailed | A Autenticação Interativa foi chamada com o parâmetro prompt=never, forçando a MSAL a depender dos cookies do navegador, sem exibir o navegador. Isso falhou. | Chamar AcquireTokenInteractively() sem Prompt.None |
| FalhaAoAdquirirTokenSilenciosamente | O SDK da MSAL não tem informações suficientes para buscar um token do cache. Isso pode ser porque nenhum token está no cache ou uma conta não foi encontrada. A mensagem de erro tem mais detalhes. | Chame AcquireTokenInteractively(). |
| None | Não são fornecidos mais detalhes. A condição pode ser resolvida pela interação do usuário durante o fluxo de autenticação interativa. | Chame AcquireTokenInteractively(). |
.NET exemplo de código
AuthenticationResult res;
try
{
res = await application.AcquireTokenSilent(scopes, account)
.ExecuteAsync();
}
catch (MsalUiRequiredException ex) when (ex.ErrorCode == MsalError.InvalidGrantError)
{
switch (ex.Classification)
{
case UiRequiredExceptionClassification.None:
break;
case UiRequiredExceptionClassification.MessageOnly:
// You might want to call AcquireTokenInteractive(). Azure AD will show a message
// that explains the condition. AcquireTokenInteractively() will return UserCanceled error
// after the user reads the message and closes the window. The calling application may choose
// to hide features or data that result in message_only if the user is unlikely to benefit
// from the message
try
{
res = await application.AcquireTokenInteractive(scopes).ExecuteAsync();
}
catch (MsalClientException ex2) when (ex2.ErrorCode == MsalError.AuthenticationCanceledError)
{
// Do nothing. The user has seen the message
}
break;
case UiRequiredExceptionClassification.BasicAction:
// Call AcquireTokenInteractive() so that the user can, for instance accept terms
// and conditions
case UiRequiredExceptionClassification.AdditionalAction:
// You might want to call AcquireTokenInteractive() to show a message that explains the remedial action.
// The calling application may choose to hide flows that require additional_action if the user
// is unlikely to complete the remedial action (even if this means a degraded experience)
case UiRequiredExceptionClassification.ConsentRequired:
// Call AcquireTokenInteractive() for user to give consent.
case UiRequiredExceptionClassification.UserPasswordExpired:
// Call AcquireTokenInteractive() so that user can reset their password
case UiRequiredExceptionClassification.PromptNeverFailed:
// You used WithPrompt(Prompt.Never) and this failed
case UiRequiredExceptionClassification.AcquireTokenSilentFailed:
default:
// May be resolved by user interaction during the interactive authentication flow.
res = await application.AcquireTokenInteractive(scopes)
.ExecuteAsync(); break;
}
}
Desafios de acesso condicional e declarações
Ao obter tokens silenciosamente, seu aplicativo pode receber mensagens de erro quando um questionamento de declarações de Acesso Condicional, como uma política de MFA, for exigido por uma API que você está tentando acessar.
O padrão para lidar com esse erro é adquirir interativamente um token usando MSAL. Isso solicita ao usuário e oferece a ele a oportunidade de satisfazer a política de Acesso Condicional necessária.
Em determinados casos, ao chamar uma API que exige Acesso Condicional, você pode receber uma solicitação de declarações na mensagem de erro da API. Por exemplo, se a política de Acesso Condicional for ter um dispositivo gerenciado (Intune), o erro será algo como AADSTS53000: seu dispositivo precisa ser gerenciado para acessar esse recurso ou algo semelhante. Nesse caso, você pode passar as declarações na chamada de token de aquisição para que o usuário seja solicitado a atender à política apropriada.
Ao usar o MSAL.NET para chamar uma API que exige Acesso Condicional, seu aplicativo precisa lidar com exceções de desafio de declarações. Isso aparece como uma MsalServiceException em que a propriedade Claims não estará vazia.
Para lidar com o desafio de reivindicação, use WithClaims(String).
Tentar novamente após erros e exceções
É esperado que você implemente suas próprias políticas de nova tentativa ao chamar o MSAL. A MSAL faz chamadas HTTP para o serviço Microsoft Entra e, ocasionalmente, podem ocorrer falhas. Por exemplo, a rede pode ficar inoperante ou o servidor está sobrecarregado.
HTTP 429
Quando o Servidor de Token de Serviço (STS) é sobrecarregado por solicitações em excesso, ele retorna o erro HTTP 429 com uma indicação de quanto tempo falta para que você possa tentar novamente no campo de resposta Retry-After.
Códigos de erro HTTP 500-600
MSAL.NET implementa um mecanismo simples de repetição única para erros com códigos de erro HTTP 500-600.
MsalServiceException aparece System.Net.Http.Headers.HttpResponseHeaders como uma propriedade namedHeaders. Você pode usar informações adicionais do código de erro para melhorar a confiabilidade de seus aplicativos. No caso descrito, você pode usar a RetryAfter propriedade (do tipo RetryConditionHeaderValue) e calcular quando tentar novamente.
Aqui está um exemplo para um aplicativo daemon usando o fluxo de credenciais do cliente. Você pode adaptá-lo a qualquer um dos métodos para adquirir um token.
bool retry = false;
do
{
TimeSpan? delay;
try
{
result = await publicClientApplication.AcquireTokenForClient(scopes, account).ExecuteAsync();
}
catch (MsalServiceException serviceException)
{
if (serviceException.ErrorCode == "temporarily_unavailable")
{
RetryConditionHeaderValue retryAfter = serviceException.Headers.RetryAfter;
if (retryAfter.Delta.HasValue)
{
delay = retryAfter.Delta;
}
else if (retryAfter.Date.HasValue)
{
delay = (retryAfter.Date.Value – DateTimeOffset.Now).TotalMilliseconds;
}
}
}
// . . .
if (delay.HasValue)
{
Thread.Sleep((int)delay.Value.TotalMilliseconds); // sleep or other
retry = true;
}
} while (retry);
Próximas Etapas
Considere habilitar o Log no MSAL.NET para ajudar você a diagnosticar e depurar problemas.