Hibák és kivételek kezelése az MSAL.NET-ben

Ez a cikk áttekintést nyújt a gyakori bejelentkezési hibák kezelésére vonatkozó különböző típusú hibákról és javaslatokról.

Az MSAL hibakezelési alapjai

Az Microsoft Authentication Library (MSAL) kivételei az alkalmazásfejlesztőknek szólnak a hibaelhárításhoz, nem pedig a végfelhasználók számára való megjelenítéshez. A kivételüzenetek nincsenek lokalizálva.

A kivételek és hibák feldolgozásakor a kivételtípust és a hibakódot használhatja a kivételek megkülönböztetéséhez. A hibakódok listáját Microsoft Entra hitelesítési és engedélyezési hibakódok között találja.

A bejelentkezési élmény során hibák léphetnek fel a hozzájárulások, a feltételes hozzáférés (MFA, Eszközkezelés, helyalapú korlátozások), a jogkivonatok kiállítása és beváltása, valamint a felhasználói tulajdonságok terén.

Az alábbi szakasz további részleteket tartalmaz az alkalmazás hibakezeléséről.

Hibakezelés az MSAL.NET-ben

Kivételtípusok

Az MsalClientException akkor jelenik meg, ha maga a kódtár hibaállapotot észlel, például rossz konfigurációt.

Az MsalServiceException akkor jelenik meg, ha az identitásszolgáltató (Microsoft Entra ID) hibát ad vissza. Ez a kiszolgálóhiba fordítása.

Az MsalUIRequiredException az MsalServiceException típusa, és azt jelzi, hogy felhasználói beavatkozásra van szükség. Ha például többtényezős hitelesítésre (MFA) van szükség, vagy ha a felhasználó módosítja a jelszavát, és a jogkivonat nem kérhető le csendben.

Kivételek feldolgozása

.NET kivételek feldolgozásakor a kivételtípust és a tagot használhatja a ErrorCode kivételek megkülönböztetésére. ErrorCode az értékek MsalError típusú állandók.

Az MsalClientException, az MsalServiceException és az MsalUIRequiredException mezőket is megtekintheti.

Ha az MsalServiceException parancs ki van dobva, próbálkozzon a hitelesítési és engedélyezési hibakódokkal , és ellenőrizze, hogy a kód szerepel-e a listában.

Ha a MsalUIRequiredException parancsot eldobják, az azt jelzi, hogy a felhasználónak interaktív folyamatra van szüksége a probléma megoldásához. Az olyan nyilvános ügyfélalkalmazásokban, mint az asztali és a mobilalkalmazás, ezt egy böngészőt megjelenítő hívással AcquireTokenInteractiveoldjuk meg. A bizalmas ügyfélalkalmazásokban a webalkalmazások átirányítják a felhasználót az engedélyezési lapra, a webes API-k pedig a hitelesítési hibára utaló HTTP-állapotkódot és fejlécet (401 Jogosulatlan és WWW-Authenticate fejlécet) adnak vissza.

Gyakori .NET kivételek

Az alábbiakban néhány gyakori kivételt és néhány lehetséges megoldási lehetőséget talál:

Exception Hibakód Mitigation
MsalUiRequiredException AADSTS65001: A felhasználó vagy a rendszergazda nem járult hozzá a(z) '{appId}' azonosítójú, '{appName}' nevű alkalmazás használatához. Interaktív engedélyezési kérés küldése ehhez a felhasználóhoz és erőforráshoz. Először kérje le a felhasználói hozzájárulást. Ha nem .NET Core-t használ (amely nem rendelkezik webes felhasználói felülettel), hívja meg (csak egyszer) AcquireTokenInteractive. Ha a .NET Core-t használja, vagy nem szeretne AcquireTokenInteractive műveletet végezni, a felhasználó a hozzájárulás megadásához megnyithat egy URL-címet: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read. híváshoz AcquireTokenInteractive: app.AcquireTokenInteractive(scopes).WithAccount(account).WithClaims(ex.Claims).ExecuteAsync();
MsalUiRequiredException AADSTS50079: A felhasználónak többtényezős hitelesítést (MFA) kell használnia. Nincs kockázatcsökkentés. Ha az MFA a bérlőnél van konfigurálva, és a Microsoft Entra ID úgy dönt, hogy annak használatát kikényszeríti, váltson interaktív folyamatra, például a következőre: AcquireTokenInteractive.
MsalServiceException AADSTS90010: A támogatás típusa nem támogatott a /common vagy /consumers végpontokon. Használja a /organizations vagy a bérlőspecifikus végpontot. A /common parancsot használta. Ahogy a Microsoft Entra ID üzenete is ismerteti, a szolgáltatónak bérlővel vagy más módon /szervezettel kell rendelkeznie.
MsalServiceException AADSTS70002: A kérelem törzsének a következő paramétert kell tartalmaznia: client_secret or client_assertion. Ez a kivétel akkor dobódhat, ha az alkalmazás nincs nyilvános ügyfélalkalmazásként regisztrálva a Microsoft Entra ID-ban. A Microsoft Entra felügyeleti központban szerkessze az alkalmazás jegyzékét, és állítsa a(z) allowPublicClient értékét erre: true.
MsalClientException unknown_user Message: Nem sikerült azonosítani a bejelentkezett felhasználót A kódtár nem tudta lekérdezni a jelenleg a Windowsba bejelentkezett felhasználót, vagy ez a felhasználó nincs Active Directoryhoz vagy Microsoft Entra-azonosítóhoz csatlakoztatva (a munkahelyhez csatlakoztatott felhasználók nem támogatottak). Megoldás: Valósítson meg saját logikát a felhasználónév lekérésére (például john@contoso.com), és használja a AcquireTokenByIntegratedWindowsAuth felhasználónevet fogadó változatát.
MsalClientException A kezelt felhasználók számára az integrált Windows-hitelesítés nem támogatott. Ez a módszer a Active Directory (AD) által közzétett protokollra támaszkodik. Ha egy felhasználó Microsoft Entra ID lett létrehozva AD-háttérrendszer ("felügyelt" felhasználó) nélkül, ez a módszer meghiúsul. Az AD-ben létrehozott és Microsoft Entra ID ("összevont" felhasználók) által támogatott felhasználók élvezhetik ezt a nem interaktív hitelesítési módszert. Kockázatcsökkentés: Interaktív hitelesítés használata.

MsalUiRequiredException

Az MSAL.NET által a(z) AcquireTokenSilent() meghívásakor visszaadott gyakori állapotkódok egyike a(z) MsalError.InvalidGrantError. Ez az állapotkód azt jelenti, hogy az alkalmazásnak újra meg kell hívnia a hitelesítési kódtárat, de interaktív módban (a Nyilvános ügyfélalkalmazásokhoz készült AcquireTokenInteractive vagy a AcquireTokenByDeviceCodeFlow használata kihívást jelent a webalkalmazásokban). Ennek az az oka, hogy további felhasználói beavatkozásra van szükség a hitelesítési jogkivonat kiállítása előtt.

A legtöbb esetben, amikor a(z) AcquireTokenSilent meghiúsul, annak az az oka, hogy a tokengyorsítótár nem tartalmaz a kérésének megfelelő tokeneket. A hozzáférési jogkivonatok 1 óra múlva lejárnak, és AcquireTokenSilent egy frissítési jogkivonat alapján próbálnak lekérni egy újat (OAuth2-ben ez a "Token frissítése" folyamat). Ez a folyamat több okból is meghiúsulhat, például ha egy bérlői rendszergazda szigorúbb bejelentkezési szabályzatokat konfigurál.

Az interakció célja, hogy a felhasználó végrehajtsa a műveletet. Ezen feltételek némelyike könnyen megoldható a felhasználók számára (például egyetlen kattintással elfogadhatók a használati feltételek), és néhányat nem lehet megoldani az aktuális konfigurációval (például a szóban forgó gépnek csatlakoznia kell egy adott vállalati hálózathoz). Vannak, akik segítenek a felhasználónak beállítani a többtényezős hitelesítést, vagy telepíteni Microsoft Authenticator az eszközükön.

MsalUiRequiredException besorolási felsorolás

Az MSAL egy Classification mezőt tesz elérhetővé, amelyet elolvashat, hogy jobb felhasználói élményt nyújtson. Ha például meg szeretné mondani a felhasználónak, hogy lejárt a jelszava, vagy hogy hozzájárulást kell adnia bizonyos erőforrások használatához. A támogatott értékek az UiRequiredExceptionClassification enumerálás részét képezik:

Classification Meaning Ajánlott kezelés
BasicAction A feltétel a felhasználói beavatkozással oldható meg az interaktív hitelesítési folyamat során. Hívja meg az AcquireTokenInteractively() függvényt.
További művelet A feltétel az interaktív hitelesítési folyamaton kívül a rendszerrel való további javítóművelettel oldható meg. Hívja meg a AcquireTokenInteractively() függvényt a szervizelési műveletet magyarázó üzenet megjelenítéséhez. A hívó alkalmazás elrejtheti a additional_action igénylő folyamatokat, ha a felhasználó nem valószínű, hogy végrehajtja a szervizelési műveletet.
MessageOnly A feltétel jelenleg nem oldható fel. Az interaktív hitelesítési folyamat elindításakor megjelenik egy üzenet, amely ismerteti a feltételt. Hívja meg a AcquireTokenInteractively() függvényt a feltételt magyarázó üzenet megjelenítéséhez. A AcquireTokenInteractively() visszaadja a UserCanceled hibát, miután a felhasználó elolvasta az üzenetet, és bezárta az ablakot. A hívó alkalmazás elrejtheti azokat a folyamatokat, amelyek message_only eredményeznek, ha a felhasználó nem valószínű, hogy kihasználja az üzenetet.
Beleegyezés szükséges Hiányzik vagy visszavonták a felhasználói hozzájárulást. Hívja meg a AcquireTokenInteractively() függvényt a felhasználó hozzájárulásának megadásához.
UserPasswordExpired A felhasználó jelszava lejárt. Hívja meg a AcquireTokenInteractively() parancsot, hogy a felhasználó visszaállíthassa a jelszavát.
PromptNeverFailed Az interaktív hitelesítés a prompt=never paraméterrel lett meghívva, arra kényszerítve az MSAL-t, hogy a böngésző cookie-jára támaszkodjon, és ne jelenítse meg a böngészőt. Ez nem sikerült. Hívja meg az AcquireTokenInteractively() függvényt a Prompt.None használata nélkül
AcquireTokenSilentFailed Az MSAL SDK számára nem áll rendelkezésre elegendő információ ahhoz, hogy tokent kérjen le a gyorsítótárból. Ennek az lehet az oka, hogy nincsenek tokenek a gyorsítótárban, vagy nem található fiók. A hibaüzenet további részleteket tartalmaz. Hívja meg az AcquireTokenInteractively() függvényt.
Nincs További részletek nincsenek megadva. A feltétel az interaktív hitelesítési folyamat során felhasználói beavatkozással oldható fel. Hívja meg az AcquireTokenInteractively() függvényt.

példakód .NET

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

Feltételes hozzáféréssel és jogcímekkel kapcsolatos kihívások

A tokenek csendes lekérése során az alkalmazás hibákat kaphat, ha az elérni kívánt API Feltételes hozzáférés jogcímkérését követeli meg, például MFA-szabályzat miatt.

A hiba kezelésének módja az, hogy az MSAL használatával interaktívan szerzünk be egy tokent. Ez kéri a felhasználót, és lehetőséget ad nekik a szükséges feltételes hozzáférési szabályzat teljesítésére.

Bizonyos esetekben, amikor feltételes hozzáférést igénylő API-t hív meg, az API által visszaadott hibában jogcímigényt kaphat. Ha például a Feltételes hozzáférési szabályzat megköveteli a felügyelt eszköz (Intune) használatát, a hibaüzenet valami ilyesmi lesz: AADSTS53000: Az eszköznek felügyeltnek kell lennie ennek az erőforrásnak az eléréséhez, vagy valami hasonló. Ebben az esetben átadhatja a claim-eket a tokenlekérési hívásban, hogy a felhasználó felszólítást kapjon a megfelelő szabályzat követelményeinek teljesítésére.

Ha az alkalmazás MSAL.NET használatával feltételes hozzáférést igénylő API-t hív meg, kezelnie kell a jogcímigénylési kihívásokhoz kapcsolódó kivételeket. Ez MsalServiceExceptionként jelenik meg, amelyben a Claims tulajdonság nem üres.

A jogcímigény vitatásának kezeléséhez használja a(z) WithClaims(String) elemet.

Újrapróbálkozás hibák és kivételek után

Az MSAL hívása során saját újrapróbálkozési szabályzatokat kell implementálnia. Az MSAL HTTP-hívásokat indít a Microsoft Entra szolgáltatáshoz, és időnként hibák léphetnek fel. A hálózat például leállhat, vagy a kiszolgáló túlterhelt.

HTTP 429

Ha a Service Token Server (STS) túl sok kérés miatt túlterhelt, HTTP 429-es hibát ad vissza, a Retry-After válaszmezőben pedig jelzi, hogy mennyi idő múlva próbálkozhat újra.

HTTP-hibakódok 500-600

MSAL.NET egy egyszerű újrapróbálkozásos mechanizmust implementál az 500-600-os HTTP-hibakódokkal kapcsolatos hibákhoz.

A(z) MsalServiceException a(z) System.Net.Http.Headers.HttpResponseHeaders elemet namedHeaders tulajdonságként teszi elérhetővé. A hibakód további információi segítségével javíthatja az alkalmazások megbízhatóságát. A leírt esetben használhatja a RetryAfter tulajdonságot (típus RetryConditionHeaderValue) és kiszámíthatja, hogy mikor kell újrapróbálkoznia.

Íme egy példa egy démonalkalmazásra az ügyfél hitelesítő adatainak folyamatával. Ezt a token beszerzésére szolgáló bármely módszerhez igazíthatja.


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

Következő lépések

Fontolja meg az MSAL.NET naplózás engedélyezését, hogy segítsen a problémák diagnosztizálásában és hibakeresésében.