Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Ten artykuł zawiera omówienie różnych typów błędów i zaleceń dotyczących obsługi typowych błędów logowania.
Podstawy obsługi błędów w MSAL
Wyjątki w Microsoft Authentication Library (MSAL) są przeznaczone dla deweloperów aplikacji do rozwiązywania problemów, a nie wyświetlania użytkownikom końcowym. Komunikaty o wyjątkach nie są zlokalizowane.
Podczas przetwarzania wyjątków i błędów można użyć samego typu wyjątku i kodu błędu, aby odróżnić wyjątki. Aby uzyskać listę kodów błędów, zobacz Microsoft Entra kody błędów uwierzytelniania i autoryzacji.
Podczas logowania mogą wystąpić błędy dotyczące zgody, dostępu warunkowego (MFA, Zarządzanie urządzeniami, ograniczeń opartych na lokalizacji), wystawiania i realizacji tokenów oraz właściwości użytkownika.
Poniższa sekcja zawiera więcej szczegółowych informacji na temat obsługi błędów dla aplikacji.
Obsługa błędów w MSAL.NET
Typy wyjątków
Błąd MsalClientException jest zgłaszany, gdy sama biblioteka wykryje stan błędu, taki jak nieprawidłowa konfiguracja.
Wyjątek MsalServiceException jest zgłaszany, gdy dostawca tożsamości (Microsoft Entra ID) zwraca błąd. Jest to tłumaczenie błędu serwera.
MsalUIRequiredException jest typem msalServiceException i wskazuje, że interakcja użytkownika jest wymagana. Na przykład gdy wymagane jest uwierzytelnianie wieloskładnikowe (MFA) lub gdy użytkownik zmieni hasło i token nie może być uzyskiwany w trybie dyskretnym.
Przetwarzanie wyjątków
Podczas przetwarzania wyjątków platformy .NET można użyć samego typu wyjątku i składowej ErrorCode, aby rozróżniać wyjątki.
ErrorCode wartości to stałe typu MsalError.
Możesz również zapoznać się z polami msalClientException, MsalServiceException i MsalUIRequiredException.
Jeśli zostanie zgłoszony wyjątek MsalServiceException, sprawdź w Kody błędów uwierzytelniania i autoryzacji, czy ten kod jest tam wymieniony.
Jeśli zostanie zgłoszony wyjątek MsalUIRequiredException, oznacza to, że konieczne jest przeprowadzenie przepływu interaktywnego, aby użytkownik mógł rozwiązać problem. W publicznych aplikacjach klienckich, takich jak aplikacje klasyczne i mobilne, rozwiązuje się to przez wywołanie AcquireTokenInteractive, które wyświetla przeglądarkę. W poufnych aplikacjach klienckich aplikacje internetowe powinny przekierowywać użytkownika do strony autoryzacji, a internetowe interfejsy API powinny zwracać kod stanu HTTP i nagłówek wskazujący błąd uwierzytelniania (401 Brak autoryzacji i nagłówek WWW-Authenticate).
Typowe wyjątki .NET
Poniżej przedstawiono typowe wyjątki, które mogą zostać zgłoszone i niektóre możliwe środki zaradcze:
| Exception | Kod błędu | Mitigation |
|---|---|---|
| MsalUiRequiredException | AADSTS65001: użytkownik lub administrator nie wyraził zgody na używanie aplikacji o identyfikatorze "{appId}" o nazwie {appName}. Wyślij interakcyjne żądanie autoryzacji dla tego użytkownika i zasobu. | Najpierw uzyskaj zgodę użytkownika. Jeśli nie używasz platformy .NET Core (która nie ma żadnego interfejsu użytkownika w sieci Web), wywołaj (tylko raz) AcquireTokenInteractive. Jeśli używasz .NET core lub nie chcesz wykonywać czynnościAcquireTokenInteractive, użytkownik może przejść do adresu URL, aby wyrazić zgodę: https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id={clientId}&response_type=code&scope=user.read. wywołać AcquireTokenInteractive: app.AcquireTokenInteractive(scopes).WithAccount(account).WithClaims(ex.Claims).ExecuteAsync(); |
| MsalUiRequiredException | AADSTS50079: użytkownik jest wymagany do korzystania z uwierzytelniania wieloskładnikowego (MFA). | Nie ma środka zaradczego. Jeśli dla dzierżawcy skonfigurowano uwierzytelnianie wieloskładnikowe, a Microsoft Entra ID zdecyduje się je wymusić, przejdź do przepływu interaktywnego, na przykład AcquireTokenInteractive. |
| MsalServiceException | AADSTS90010: typ uprawnienia nie jest obsługiwany w punktach końcowych /common lub /consumers. Użyj /organizations lub punktu końcowego specyficznego dla dzierżawy. Użyto elementu /common. | Jak wyjaśniono w komunikacie z Microsoft Entra ID, urząd musi mieć dzierżawę lub w inny sposób /organizations. |
| MsalServiceException | AADSTS70002: Treść żądania musi zawierać następujący parametr: client_secret or client_assertion. |
Ten wyjątek może zostać zgłoszony, jeśli Twoja aplikacja nie została zarejestrowana jako publiczna aplikacja kliencka w Microsoft Entra ID. W centrum administracyjnym Microsoft Entra edytuj manifest aplikacji i ustaw allowPublicClient na true. |
| MsalClientException |
unknown_user Message: Nie można zidentyfikować zalogowanego użytkownika |
Biblioteka nie mogła ustalić aktualnie zalogowanego użytkownika systemu Windows albo ten użytkownik nie jest przyłączony do usługi Active Directory ani Microsoft Entra (użytkownicy przyłączeni do miejsca pracy nie są obsługiwani). Środki zaradcze: zaimplementuj własną logikę, aby pobrać nazwę użytkownika (na przykład john@contoso.com) i użyć AcquireTokenByIntegratedWindowsAuth formularza, który przyjmuje nazwę użytkownika. |
| MsalClientException | zintegrowane_uwierzytelnianie_systemu_windows_nieobslugiwane_uzytkownik_zarzadzany | Ta metoda opiera się na protokole udostępnianym przez Active Directory (AD). Jeśli użytkownik został utworzony w Microsoft Entra ID bez powiązania z usługą AD („użytkownik zarządzany”), ta metoda kończy się niepowodzeniem. Użytkownicy utworzeni w usłudze AD i wspierani przez Microsoft Entra ID ("użytkownicy federacyjni") mogą korzystać z tej nieinterakcyjnej metody uwierzytelniania. Środki zaradcze: użyj uwierzytelniania interakcyjnego. |
MsalUiRequiredException
Jednym z typowych kodów stanu zwracanych przez MSAL.NET przy wywołaniu AcquireTokenSilent() jest MsalError.InvalidGrantError. Ten kod stanu oznacza, że aplikacja powinna ponownie wywołać bibliotekę uwierzytelniania, ale w trybie interaktywnym (AcquireTokenInteractive lub AcquireTokenByDeviceCodeFlow dla publicznych aplikacji klienckich ma wyzwanie w aplikacjach internetowych). Jest to spowodowane tym, że wymagana jest dodatkowa interakcja użytkownika przed wystawieniem tokenu uwierzytelniania.
W większości przypadków, gdy AcquireTokenSilent kończy się niepowodzeniem, dzieje się tak, ponieważ pamięć podręczna tokenów nie zawiera tokenów pasujących do Twojego żądania. Tokeny dostępu wygasają po 1 godzinie, a AcquireTokenSilent próbuje pobrać nowy przy użyciu tokenu odświeżania (w terminologii OAuth2 jest to przepływ „Refresh Token”). Ten przepływ może również zakończyć się niepowodzeniem z różnych powodów, na przykład jeśli administrator dzierżawy konfiguruje bardziej rygorystyczne zasady logowania.
Interakcja ma na celu umożliwienie użytkownikowi wykonania akcji. Niektóre z tych warunków można łatwo rozwiązać (na przykład zaakceptować warunki użytkowania jednym kliknięciem), a niektóre z nich nie mogą zostać rozwiązane przy użyciu bieżącej konfiguracji (na przykład maszyna, o których mowa, musi nawiązać połączenie z określoną siecią firmową). Niektóre ułatwiają użytkownikowi konfigurowanie uwierzytelniania wieloskładnikowego lub instalowanie Microsoft Authenticator na urządzeniu.
MsalUiRequiredException wyliczenie klasyfikacyjne
Biblioteka MSAL udostępnia pole Classification, które można odczytać, aby zapewnić lepszą obsługę użytkownika. Na przykład, aby poinformować użytkownika, że hasło wygasło lub że musi wyrazić zgodę na korzystanie z niektórych zasobów. Obsługiwane wartości są częścią wyliczenia UiRequiredExceptionClassification :
| Classification | Meaning | Zalecana obsługa |
|---|---|---|
| Akcja podstawowa | Problem można rozwiązać dzięki interakcji użytkownika w trakcie interaktywnego procesu uwierzytelniania. | Wywołaj metodę AcquireTokenInteractively(). |
| Dodatkowa akcja | Warunek można rozwiązać przez dodatkową interakcję korygacyjną z systemem poza przepływem uwierzytelniania interakcyjnego. | Wywołaj metodę AcquireTokenInteractively(), aby wyświetlić komunikat wyjaśniający akcję korygjącą. Aplikacja wywołująca może zdecydować o ukryciu przepływów wymagających dodatkowego działania, jeśli jest mało prawdopodobne, że użytkownik wykona działanie naprawcze. |
| Tylko komunikat | Obecnie nie można rozwiązać tego warunku. Uruchomienie przepływu uwierzytelniania interakcyjnego spowoduje wyświetlenie komunikatu objaśniającego warunek. | Wywołaj metodę AcquireTokenInteractively(), aby wyświetlić komunikat, który wyjaśnia warunek. Funkcja AcquireTokenInteractively() zwróci błąd UserCanceled po odczytaniu komunikatu przez użytkownika i zamknięciu okna. Aplikacja wywołująca może zdecydować o ukryciu przepływów, które kończą się wynikiem `message_only`, jeśli użytkownik prawdopodobnie nie odniesie korzyści z komunikatu. |
| Wymagana zgoda | Brak zgody użytkownika lub została odwołana. | Wywołaj metodę AcquireTokenInteractively(), aby użytkownik wyraził zgodę. |
| Hasło użytkownika wygasło | Hasło użytkownika wygasło. | Wywołaj metodę AcquireTokenInteractively(), aby użytkownik mógł zresetować swoje hasło. |
| PromptNeverFailed | Uwierzytelnianie interakcyjne było wywoływane z parametrem prompt=never, zmuszając bibliotekę MSAL do polegania na plikach cookie przeglądarki, a nie na wyświetlaniu przeglądarki. To się nie powiodło. | Wywołaj metodę AcquireTokenInteractively() bez monitu.None |
| AcquireTokenSilentFailed | Zestaw SDK MSAL nie ma wystarczających informacji, aby pobrać token z pamięci podręcznej. Może to być spowodowane brakiem tokenów w pamięci podręcznej lub nie znaleziono konta. Komunikat o błędzie zawiera więcej szczegółów. | Wywołaj metodę AcquireTokenInteractively(). |
| Żadne | Nie podano żadnych dalszych szczegółów. Warunek może zostać rozwiązany przez interakcję użytkownika podczas przepływu uwierzytelniania interakcyjnego. | Wywołaj metodę AcquireTokenInteractively(). |
przykład kodu .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;
}
}
Wyzwania związane z dostępem warunkowym i oświadczeniami
Podczas cichego uzyskiwania tokenów w aplikacji może wystąpić błąd, gdy interfejs API, do którego próbujesz uzyskać dostęp, wymaga żądania oświadczeń w ramach dostępu warunkowego, na przykład zasady uwierzytelniania wieloskładnikowego.
Sposób obsługi tego błędu polega na interaktywnym uzyskaniu tokenu za pomocą MSAL. Spowoduje to wyświetlenie użytkownikowi monitu i umożliwi mu spełnienie wymagań określonych przez wymaganą politykę dostępu warunkowego.
W niektórych przypadkach podczas wywoływania interfejsu API wymagającego dostępu warunkowego możesz otrzymać wyzwanie dotyczące oświadczeń w błędzie z interfejsu API. Na przykład jeśli zasada dostępu warunkowego wymaga zarządzanego urządzenia (Intune), błąd będzie wyglądał mniej więcej tak: AADSTS53000: Twoje urządzenie musi być zarządzane, aby uzyskać dostęp do tego zasobu lub czymś podobnym. W takim przypadku można przekazać oświadczenia w wywołaniu tokenu uzyskiwania, aby użytkownik był monitowany o spełnienie odpowiednich zasad.
Podczas wywoływania interfejsu API, który wymaga Dostępu warunkowego, za pomocą biblioteki MSAL.NET aplikacja musi obsługiwać wyjątki typu claim challenge. Pojawia się to jako MsalServiceException, gdzie właściwość Claims nie będzie pusta.
Aby obsłużyć weryfikację roszczenia, użyj polecenia WithClaims(String).
Ponawianie próby po wystąpieniu błędów i wyjątków
Oczekuje się od użytkownika zaimplementowania własnych zasad ponawiania prób podczas wywoływania biblioteki MSAL. Biblioteka MSAL wysyła żądania HTTP do usługi Microsoft Entra i sporadycznie mogą występować niepowodzenia. Na przykład sieć może spaść lub serwer jest przeciążony.
HTTP 429
Gdy serwer tokenów usługi (STS) jest przeciążony zbyt wieloma żądaniami, zwraca błąd HTTP 429 z wskazówką o tym, jak długo można spróbować ponownie w Retry-After polu odpowiedzi.
Kody błędów HTTP 500-600
MSAL.NET implementuje prosty mechanizm jednokrotnego ponawiania prób w przypadku błędów HTTP z kodami 500–600.
MsalServiceException udostępnia System.Net.Http.Headers.HttpResponseHeaders jako właściwość namedHeaders. Aby zwiększyć niezawodność aplikacji, możesz użyć dodatkowych informacji z kodu błędu. W opisanym przypadku można użyć właściwości RetryAfter (typu RetryConditionHeaderValue) i obliczyć, kiedy ponowić próbę.
Oto przykład aplikacji demona korzystającej z przepływu poświadczeń klienta. Można to dostosować do dowolnej z metod uzyskiwania tokenu.
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);
Następne kroki
Rozważ włączenie rejestrowania w MSAL.NET, aby ułatwić diagnozowanie i debugowanie problemów.