Hantera fel och undantag i MSAL.NET

Den här artikeln ger en översikt över de olika typerna av fel och rekommendationer för hantering av vanliga inloggningsfel.

Grunderna för MSAL-felhantering

Undantag i Microsofts autentiseringsbibliotek (MSAL) är avsedda för apputvecklare att felsöka, inte för att visas för slutanvändare. Undantagsmeddelanden är inte lokaliserade.

När du bearbetar undantag och fel kan du använda själva undantagstypen och felkoden för att skilja mellan undantag. En lista över felkoder finns i felkoder för Microsoft Entra autentisering och auktorisering.

Under inloggningen kan det uppstå fel om medgivanden, villkorsstyrd åtkomst (MFA, Správa zariadení, platsbaserade begränsningar), tokenutfärdande och inlösen samt användaregenskaper.

Följande avsnitt innehåller mer information om felhantering för din app.

Felhantering i MSAL.NET

Undantagstyper

MsalClientException genereras när själva biblioteket identifierar ett feltillstånd, till exempel en felaktig konfiguration.

MsalServiceException genereras när identitetsprovidern (Microsoft Entra ID) returnerar ett fel. Det är en översättning av serverfelet.

MsalUIRequiredException är en typ av MsalServiceException och anger att användarinteraktion krävs. Till exempel när multifaktorautentisering (MFA) krävs eller när användaren ändrar sitt lösenord och en token inte kan hämtas tyst.

Behandling av undantag

När du bearbetar .NET undantag kan du använda själva undantagstypen och ErrorCode medlemmen för att skilja mellan undantag. ErrorCode värden är konstanter av typen MsalError.

Du kan också ta en titt på fälten MsalClientException, MsalServiceException och MsalUIRequiredException.

Om MsalServiceException genereras kan du prova felkoder för autentisering och auktorisering för att se om koden visas där.

Om MsalUIRequiredException genereras är det en indikation på att ett interaktivt flöde måste ske för att användaren ska kunna lösa problemet. I offentliga klientappar som skrivbords- och mobilappar löses detta genom att anropa AcquireTokenInteractive, som visar en webbläsare. I konfidentiella klientappar bör webbappar omdirigera användaren till auktoriseringssidan och webb-API:er ska returnera en HTTP-statuskod och ett huvud som tyder på autentiseringsfelet (401 Obehörig och ett WWW-Authenticate-huvud).

Vanliga .NET undantag

Här är de vanligaste undantagen som kan uppstå och några möjliga åtgärder:

Exception Felkod Mitigation
MsalUiRequiredException AADSTS65001: Användaren eller administratören har inte samtyckt till att använda programmet med ID {appId} med namnet {appName}. Skicka en interaktiv auktoriseringsbegäran för den här användaren och resursen. Få användarmedgivande först. Om du inte använder .NET Core (som inte har något webbgränssnitt) anropar du (endast en gång) AcquireTokenInteractive. Om du använder .NET Core eller inte vill göra en AcquireTokenInteractive, kan användaren gå till en URL för att ge sitt samtycke: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read. för att anropa AcquireTokenInteractive: app.AcquireTokenInteractive(scopes).WithAccount(account).WithClaims(ex.Claims).ExecuteAsync();
MsalUiRequiredException AADSTS50079: Användaren måste använda multifaktorautentisering (MFA). Det finns ingen motåtgärd. Om MFA har konfigurerats för din klientorganisation och Microsoft Entra ID avgör att det ska krävas, använder du i stället ett interaktivt flöde som AcquireTokenInteractive.
MsalServiceException AADSTS90010: Beviljandetypen stöds inte för /common- eller /consumers-slutpunkterna. Använd /organizations eller den tenantspecifika slutpunkten. Du använde /common. Som anges i meddelandet från Microsoft Entra ID måste auktoriteten ha en klientorganisation eller annars /organizations.
MsalServiceException AADSTS70002: Begärandetexten måste innehålla följande parameter: client_secret or client_assertion. Det här undantaget kan utlöses om programmet inte har registrerats som ett offentligt klientprogram i Microsoft Entra ID. I Microsoft Entra administrationscenter redigerar du manifestet för ditt program och anger allowPublicClient till true.
MsalClientException unknown_user Message: Det gick inte att identifiera inloggad användare Biblioteket kunde inte fråga den aktuella Windows inloggade användaren eller så är den här användaren inte služba Active Directory eller Microsoft Entra ansluten (arbetsplatsanslutna användare stöds inte). Åtgärd: Implementera din egen logik för att hämta användarnamnet (till exempel john@contoso.com) och använda formuläret AcquireTokenByIntegratedWindowsAuth som innehåller användarnamnet.
MsalClientException integrated_windows_auth_not_supported_managed_user Den här metoden förlitar sig på ett protokoll som exponeras av služba Active Directory (AD). Om en användare skapades i Microsoft Entra ID utan AD-stöd ("hanterad" användare) misslyckas den här metoden. Användare som skapats i AD och som backas upp av Microsoft Entra ID ("federerade" användare) kan dra nytta av den här icke-interaktiva autentiseringsmetoden. Åtgärd: Använd interaktiv autentisering.

MsalUiRequiredException

En av de vanliga statuskoder som returneras från MSAL.NET när du anropar AcquireTokenSilent() är MsalError.InvalidGrantError. Den här statuskoden innebär att programmet ska anropa autentiseringsbiblioteket igen, men i interaktivt läge (AcquireTokenInteractive eller AcquireTokenByDeviceCodeFlow för offentliga klientprogram har det en utmaning i webbappar). Detta beror på att ytterligare användarinteraktion krävs innan autentiseringstoken kan utfärdas.

Oftast, när AcquireTokenSilent misslyckas, beror det på att tokencachen inte innehåller token som matchar din förfrågan. Åtkomsttoken upphör att gälla om 1 timme och AcquireTokenSilent försöker hämta en ny baserat på en uppdateringstoken (i OAuth2-termer är detta flödet "Uppdatera token"). Det här flödet kan också misslyckas av olika orsaker, till exempel om en klientorganisationsadministratör konfigurerar strängare inloggningsprinciper.

Interaktionen syftar till att låta användaren utföra en åtgärd. Vissa av dessa villkor är enkla för användare att lösa (till exempel acceptera användningsvillkor med ett enda klick), och vissa kan inte lösas med den aktuella konfigurationen (till exempel måste datorn i fråga ansluta till ett specifikt företagsnätverk). Vissa hjälper användaren att konfigurera multifaktorautentisering eller installera Microsoft Authenticator på sin enhet.

MsalUiRequiredException klassificeringsuppräkning

MSAL exponerar ett Classification fält som du kan läsa för att ge en bättre användarupplevelse. Till exempel för att tala om för användaren att lösenordet har upphört att gälla eller att de måste ge sitt medgivande till att använda vissa resurser. De värden som stöds är en del av UiRequiredExceptionClassification uppräkningen:

Classification Meaning Rekommenderad hantering
BasicAction Villkoret kan lösas genom användarinteraktion under det interaktiva autentiseringsflödet. Anropa AcquireTokenInteractively().
Ytterligare åtgärd Villkoret kan lösas genom ytterligare reparationsinteraktion med systemet, utanför det interaktiva autentiseringsflödet. Anropa AcquireTokenInteractively() för att visa ett meddelande som förklarar åtgärden. Anropande program kan välja att dölja flöden som kräver additional_action om det är osannolikt att användaren slutför åtgärden.
Endast meddelande Villkoret kan inte lösas just nu. När du startar ett interaktivt autentiseringsflöde visas ett meddelande som förklarar villkoret. Anropa AcquireTokenInteractively() för att visa ett meddelande som förklarar villkoret. AcquireTokenInteractively() returnerar UserCanceled-fel när användaren har läst meddelandet och stänger fönstret. Anropande program kan välja att dölja flöden som resulterar i message_only om användaren sannolikt inte kommer att dra nytta av meddelandet.
Samtycke krävs Användarmedgivande saknas eller har återkallats. Anropa AcquireTokenInteractively() för att användaren ska ge sitt medgivande.
Användarlösenordet har upphört att gälla Användarens lösenord har upphört att gälla. Anropa AcquireTokenInteractively() så att användaren kan återställa sitt lösenord.
PromptNeverFailed Interaktiv autentisering anropades med parametern prompt=never, vilket tvingade MSAL att förlita sig på webbläsarcookies och inte visa webbläsaren. Detta har misslyckats. Anropa AcquireTokenInteractively() utan Prompt.None
AcquireTokenSilentFailed MSAL SDK har inte tillräckligt med information för att hämta en token från cacheminnet. Det kan bero på att inga token finns i cacheminnet eller att ett konto inte hittades. Felmeddelandet innehåller mer information. Anropa AcquireTokenInteractively().
Ingen Inga ytterligare detaljer tillhandahålls. Villkoret kan lösas av användarinteraktion under det interaktiva autentiseringsflödet. Anropa AcquireTokenInteractively().

.NET kodexempel

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

Villkorsstyrd åtkomst och claims-utmaningar

När du hämtar token utan användarinteraktion kan din applikation få fel om ett API som du försöker komma åt kräver en anspråksutmaning för villkorlig åtkomst, till exempel en MFA-policy.

Mönstret för att hantera det här felet är att interaktivt hämta en token med hjälp av MSAL. Detta uppmanar användaren och ger dem möjlighet att uppfylla den nödvändiga principen för villkorsstyrd åtkomst.

I vissa fall, när du anropar ett API som kräver villkorsstyrd åtkomst, kan du få en anspråksutmaning i felmeddelandet från API:et. Om principen för villkorsstyrd åtkomst till exempel ska ha en hanterad enhet (Intune) blir felet ungefär som AADSTS53000: Enheten måste hanteras för att få åtkomst till den här resursen eller något liknande. I det här fallet kan du skicka med anspråken i anropet för att hämta en token så att användaren uppmanas att uppfylla kraven i rätt policy.

När du anropar ett API som kräver villkorlig åtkomst från MSAL.NET måste ditt program hantera undantag för anspråksutmaningar. Detta visar sig som en MsalServiceException och egenskapen Claims kommer inte att vara tom.

Om du vill hantera anspråksutmaningen använder du WithClaims(String).

Försök igen efter fel och undantag

Du förväntas implementera dina egna principer för återförsök när du anropar MSAL. MSAL gör HTTP-anrop till Microsoft Entra-tjänsten och ibland kan fel uppstå. Nätverket kan till exempel gå ner eller så är servern överbelastad.

HTTP 429

När servicetokenservern (STS) är överbelastad med för många begäranden returneras HTTP-fel 429 med en ledtråd om hur lång tid tills du kan försöka igen i svarsfältet Retry-After .

HTTP-felkoder 500-600

MSAL.NET implementerar en enkel mekanism för återförsök en gång för fel med HTTP-felkoderna 500-600.

MsalServiceException visas System.Net.Http.Headers.HttpResponseHeaders som en egenskap namedHeaders. Du kan använda ytterligare information från felkoden för att förbättra tillförlitligheten för dina program. I det fall som beskrivs kan du använda RetryAfter egenskapen (av typen RetryConditionHeaderValue) och beräkna när du ska försöka igen.

Här är ett exempel för ett daemonprogram som använder flödet för klientautentiseringsuppgifter. Du kan anpassa detta till någon av metoderna för att hämta en 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);

Nästa steg

Överväg att aktivera loggning i MSAL.NET som hjälper dig att diagnostisera och felsöka problem.