Fouten en uitzonderingen in MSAL.NET verwerken

Dit artikel bevat een overzicht van de verschillende typen fouten en aanbevelingen voor het afhandelen van veelvoorkomende aanmeldingsfouten.

Basisprincipes van MSAL-foutafhandeling

Uitzonderingen in Microsoft Authentication Library (MSAL) zijn bedoeld voor app-ontwikkelaars om problemen op te lossen, niet voor weergave aan eindgebruikers. Uitzonderingsberichten worden niet gelokaliseerd.

Wanneer u uitzonderingen en fouten verwerkt, kunt u het uitzonderingstype zelf en de foutcode gebruiken om onderscheid te maken tussen uitzonderingen. Zie Microsoft Entra foutcodes voor verificatie en autorisatie voor een lijst met foutcodes.

Tijdens de aanmeldingservaring kunnen er fouten optreden over toestemmingen, voorwaardelijke toegang (MFA, Apparaatbeheer, beperkingen op basis van locatie), tokenuitgifte en inwisseling en gebruikerseigenschappen.

In de volgende sectie vindt u meer informatie over foutafhandeling voor uw app.

Foutafhandeling in MSAL.NET

Uitzonderingstypen

MsalClientException wordt gegenereerd wanneer de bibliotheek zelf een foutstatus detecteert, zoals een onjuiste configuratie.

MsalServiceException wordt gegenereerd wanneer de id-provider (Microsoft Entra ID) een fout retourneert. Dit is een vertaling van de serverfout.

MsalUIRequiredException is het type MsalServiceException en geeft aan dat gebruikersinteractie vereist is. Wanneer bijvoorbeeld meervoudige verificatie (MFA) vereist is of wanneer de gebruiker zijn wachtwoord wijzigt en een token niet op de achtergrond kan worden verkregen.

Uitzonderingen verwerken

Wanneer u .NET uitzonderingen verwerkt, kunt u het uitzonderingstype zelf en het ErrorCode lid gebruiken om onderscheid te maken tussen uitzonderingen. ErrorCode waarden zijn constanten van het type MsalError.

U kunt ook de velden MsalClientException, MsalServiceException en MsalUIRequiredException bekijken.

Als MsalServiceException wordt gegenereerd, probeert u verificatie- en autorisatiefoutcodes om te zien of de code daar wordt vermeld.

Als MsalUIRequiredException wordt opgeworpen, is dat een aanwijzing dat er een interactieve stroom moet plaatsvinden zodat de gebruiker het probleem kan oplossen. In openbare client-apps, zoals desktop- en mobiele apps, wordt dit opgelost door AcquireTokenInteractive aan te roepen, waardoor een browser wordt geopend. In vertrouwelijke client-apps moeten web-apps de gebruiker omleiden naar de autorisatiepagina en moeten web-API's een HTTP-statuscode en header retourneren die wijzen op de verificatiefout (401 Niet geautoriseerd en een WWW-Authenticate-header).

Veelvoorkomende uitzonderingen voor .NET

Hier volgen de algemene uitzonderingen die kunnen worden gegenereerd en enkele mogelijke oplossingen:

Exception Foutcode Mitigation
MsalUiRequiredException AADSTS65001: De gebruiker of beheerder heeft niet toestemming gegeven om de toepassing te gebruiken met de id {appId} met de naam {appName}. Verzend een interactieve autorisatieaanvraag voor deze gebruiker en resource. Vraag eerst toestemming van de gebruiker. Als u .NET Core niet gebruikt (dat geen webinterface heeft), roept u AcquireTokenInteractive (slechts één keer) aan. Als u .NET Core gebruikt of geen AcquireTokenInteractive wilt uitvoeren, kan de gebruiker naar een URL gaan om toestemming te geven: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read om te bellen AcquireTokenInteractive: app.AcquireTokenInteractive(scopes).WithAccount(account).WithClaims(ex.Claims).ExecuteAsync();
MsalUiRequiredException AADSTS50079: De gebruiker moet meervoudige verificatie (MFA) gebruiken. Er is geen mitigerende maatregel. Als MFA is geconfigureerd voor uw tenant en Microsoft Entra ID besluit deze af te dwingen, moet u terugvallen op een interactieve stroom, zoals AcquireTokenInteractive.
MsalServiceException AADSTS90010: Het granttype wordt niet ondersteund via de /common- of /consumers-eindpunten. Gebruik /organizations of het tenant-specifieke eindpunt. U hebt /common gebruikt. Zoals uitgelegd in het bericht van Microsoft Entra ID, moet de autoriteit een tenant of anderszins /organisaties hebben.
MsalServiceException AADSTS70002: De hoofdtekst van de aanvraag moet de volgende parameter bevatten: client_secret or client_assertion. Deze uitzondering kan worden gegenereerd als uw toepassing niet is geregistreerd als een openbare clienttoepassing in Microsoft Entra ID. Bewerk in de Microsoft Entra-beheercentrum het manifest voor uw toepassing en stel deze in op allowPublicClienttrue.
MsalClientException unknown_user Message: Kan aangemelde gebruiker niet identificeren De bibliotheek kon de momenteel bij Windows aangemelde gebruiker niet opvragen, of deze gebruiker is niet gekoppeld aan Active Directory of Microsoft Entra (aan een werkplek gekoppelde gebruikers worden niet ondersteund). Risicobeperking: Implementeer uw eigen logica om de gebruikersnaam op te halen (bijvoorbeeld john@contoso.com) en gebruik het AcquireTokenByIntegratedWindowsAuth formulier dat de gebruikersnaam inneemt.
MsalClientException Geïntegreerde Windows-verificatie wordt niet ondersteund voor beheerde gebruikers. Deze methode is afhankelijk van een protocol dat wordt weergegeven door Active Directory (AD). Als een gebruiker is gemaakt in Microsoft Entra ID zonder AD-backing ('beheerde' gebruiker), mislukt deze methode. Gebruikers die zijn gemaakt in AD en ondersteund door Microsoft Entra ID ("federatieve" gebruikers) kunnen profiteren van deze niet-interactieve verificatiemethode. Risicobeperking: interactieve verificatie gebruiken.

MsalUiRequiredException

Een van de algemene statuscodes die worden geretourneerd door MSAL.NET bij het aanroepen AcquireTokenSilent() isMsalError.InvalidGrantError. Deze statuscode betekent dat de toepassing de verificatiebibliotheek opnieuw moet aanroepen, maar in de interactieve modus (AcquireTokenInteractive of AcquireTokenByDeviceCodeFlow voor openbare clienttoepassingen, wel een uitdaging hebben in web-apps). Dit komt doordat extra gebruikersinteractie is vereist voordat het verificatietoken kan worden uitgegeven.

Meestal wanneer AcquireTokenSilent dit mislukt, komt dit doordat de tokencache geen tokens bevat die overeenkomen met uw aanvraag. Toegangstokens verlopen na 1 uur en AcquireTokenSilent probeert op basis van een refresh token een nieuw token op te halen (in OAuth2-termen is dit de 'Refresh Token'-flow). Deze stroom kan ook om verschillende redenen mislukken, bijvoorbeeld als een tenantbeheerder strengere aanmeldingsbeleidsregels configureert.

De interactie is gericht op het uitvoeren van een actie door de gebruiker. Sommige van deze voorwaarden zijn eenvoudig om gebruikers op te lossen (bijvoorbeeld gebruiksvoorwaarden accepteren met één klik) en sommige kunnen niet worden opgelost met de huidige configuratie (de betreffende computer moet bijvoorbeeld verbinding maken met een specifiek bedrijfsnetwerk). Sommige helpen de gebruiker bij het instellen van meervoudige verificatie of het installeren van Microsoft Authenticator op hun apparaat.

MsalUiRequiredException classificatie-inventarisatie

MSAL maakt een Classification veld beschikbaar, dat u kunt lezen om een betere gebruikerservaring te bieden. Als u de gebruiker bijvoorbeeld wilt vertellen dat het wachtwoord is verlopen of dat ze toestemming moeten geven om bepaalde resources te gebruiken. De ondersteunde waarden maken deel uit van de UiRequiredExceptionClassification enum:

Classification Meaning Aanbevolen verwerking
Basisactie De situatie kan worden opgelost door interactie door de gebruiker tijdens het interactieve authenticatieproces. AcquireTokenInteractively() aanroepen.
Aanvullende actie Voorwaarde kan worden opgelost door aanvullende herstelinteractie met het systeem, buiten de interactieve verificatiestroom. Roep AcquireTokenInteractively() aan om een bericht weer te geven met uitleg van de herstelactie. De aanroepende applicatie kan ervoor kiezen processen te verbergen die additional_action vereisen als de gebruiker de herstelactie waarschijnlijk niet zal voltooien.
MessageOnly De voorwaarde kan momenteel niet worden opgelost. Als u een interactieve verificatiestroom start, wordt een bericht weergegeven waarin de voorwaarde wordt uitgelegd. Roep AcquireTokenInteractively() aan om een bericht weer te geven waarin de voorwaarde wordt uitgelegd. AcquireTokenInteractively() retourneert UserCanceled-fout nadat de gebruiker het bericht heeft gelezen en het venster sluit. De aanroepende toepassing kan ervoor kiezen stromen te verbergen die resulteren in message_only als de gebruiker waarschijnlijk geen baat heeft bij het bericht.
Toestemming vereist Gebruikerstoestemming ontbreekt of is ingetrokken. Roep AcquireTokenInteractively() aan om de gebruiker toestemming te geven.
Gebruikerswachtwoord verlopen Het wachtwoord van de gebruiker is verlopen. Roep AcquireTokenInteractively() aan, zodat gebruikers hun wachtwoord opnieuw kunnen instellen.
PromptNeverFailed Interactieve authenticatie is aangeroepen met de parameter prompt=never, waardoor MSAL zich moet baseren op browsercookies en de browser niet weer te geven. Dit is mislukt. AcquireTokenInteractively() aanroepen zonder Prompt.None
AcquireTokenSilentFailed MSAL SDK beschikt niet over voldoende informatie om een token op te halen uit de cache. Dit kan zijn omdat er geen tokens in de cache staan of dat er geen account is gevonden. Het foutbericht bevat meer details. AcquireTokenInteractively() aanroepen.
Geen Er worden geen verdere details verstrekt. Deze situatie kan worden opgelost door interactie van de gebruiker tijdens het interactieve authenticatieproces. AcquireTokenInteractively() aanroepen.

voorbeeld van .NET code

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;
 }
}

Problemen met voorwaardelijke toegang en claims

Wanneer tokens op de achtergrond worden opgehaald, kan uw toepassing fouten krijgen wanneer een claims-uitdaging voor voorwaardelijke toegang, zoals MFA-beleid, wordt vereist door een API waartoe u toegang probeert te krijgen.

Het patroon voor het afhandelen van deze fout is om interactief een token te verkrijgen met BEHULP van MSAL. Hiermee wordt de gebruiker gevraagd en krijgt deze de mogelijkheid om te voldoen aan het vereiste beleid voor voorwaardelijke toegang.

In bepaalde gevallen kunt u, wanneer u een API aanroept waarvoor voorwaardelijke toegang is vereist, een claims-uitdaging ontvangen in de foutmelding van de API. Als het beleid voor voorwaardelijke toegang bijvoorbeeld een beheerd apparaat (Intune) heeft, is de fout ongeveer AADSTS53000: uw apparaat moet worden beheerd voor toegang tot deze resource of iets dergelijks. In dit geval kunt u de claims doorgeven in de aanroep van het acquire-token, zodat de gebruiker wordt gevraagd om te voldoen aan het juiste beleid.

Wanneer u een API aanroept waarvoor voorwaardelijke toegang is vereist vanuit MSAL.NET, moet uw toepassing uitzonderingen voor claimuitdaging afhandelen. Dit wordt weergegeven als een MsalServiceException waarbij de eigenschap Claims niet leeg is.

Als u de claimvraag wilt afhandelen, gebruikt u WithClaims(String).

Opnieuw proberen na fouten en uitzonderingen

U wordt verwacht dat u uw eigen beleid voor opnieuw proberen implementeert bij het aanroepen van MSAL. MSAL maakt HTTP-aanroepen naar de Microsoft Entra-service en af en toe kunnen er fouten optreden. Het netwerk kan bijvoorbeeld uitvalt of de server overbelast is.

HTTP 429

Wanneer de Service Token Server (STS) overbelast is met te veel aanvragen, retourneert deze HTTP-fout 429 met een hint over hoe lang het duurt voordat u het opnieuw kunt proberen in het Retry-After antwoordveld.

HTTP-foutcodes 500-600

MSAL.NET implementeert een eenvoudig mechanisme voor het opnieuw proberen van fouten met HTTP-foutcodes 500-600.

MsalServiceException wordt als eigenschap System.Net.Http.Headers.HttpResponseHeadersweergegevennamedHeaders. U kunt aanvullende informatie uit de foutcode gebruiken om de betrouwbaarheid van uw toepassingen te verbeteren. In het beschreven geval kunt u de eigenschap (van het RetryAfter type RetryConditionHeaderValue) gebruiken en berekenen wanneer u het opnieuw wilt proberen.

Hier volgt een voorbeeld voor een daemon-toepassing met behulp van de clientreferentiestroom. U kunt dit aanpassen aan een van de methoden voor het verkrijgen van een 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);

Volgende stappen 

Overweeg logboekregistratie in te schakelen in MSAL.NET om u te helpen bij het vaststellen en opsporen van problemen.