Behandeln von Fehlern und Ausnahmen in MSAL für iOS/macOS

In diesem Artikel finden Sie eine Übersicht über die verschiedenen Arten von Fehlern und Empfehlungen für die Behandlung häufiger Anmeldefehler.

Grundlagen zur MSAL-Fehlerbehandlung

Ausnahmen in Microsoft Authentication Library (MSAL) (MSAL) sind für App-Entwickler vorgesehen, um Probleme zu beheben, nicht für die Anzeige für Endbenutzer. Ausnahmemeldungen werden nicht lokalisiert.

Bei der Verarbeitung von Ausnahmen und Fehlern können Sie den Ausnahmetyp selbst und den Fehlercode verwenden, um zwischen Ausnahmen zu unterscheiden. Eine Liste der Fehlercodes finden Sie unter Microsoft Entra Authentifizierungs- und Autorisierungsfehlercodes.

Während der Anmeldeumgebung treten möglicherweise Fehler bezüglich Zustimmungen, bedingter Zugriff (MFA, Geräteverwaltung, Standortbasierte Einschränkungen), Tokenausstellung und Einlösung sowie Benutzereigenschaften auf.

Der folgende Abschnitt enthält weitere Details zur Fehlerbehandlung für Ihre App.

Fehlerbehandlung in MSAL für iOS/macOS

Die vollständige Liste der MSAL-Fehler für iOS und macOS ist in MSALError enum aufgelistet.

Alle von MSAL erzeugten Fehler werden mit MSALErrorDomain Domäne zurückgegeben.

Bei Systemfehlern gibt MSAL das Original NSError aus der System-API zurück. Wenn beispielsweise der Tokenerwerb aufgrund fehlender Netzwerkkonnektivität fehlschlägt, gibt MSAL einen Fehler mit der NSURLErrorDomain-Domäne und dem NSURLErrorNotConnectedToInternet-Code zurück.

Es wird empfohlen, mindestens die folgenden beiden MSAL-Fehler auf clientseitiger Seite zu behandeln:

  • MSALErrorInteractionRequired: Der Benutzer muss eine interaktive Anforderung ausführen. Es gibt viele Bedingungen, die zu diesem Fehler führen können, z. B. eine abgelaufene Authentifizierungssitzung oder die Notwendigkeit zusätzlicher Authentifizierungsanforderungen. Rufen Sie die MSAL Interactive Token Acquisition API auf, um wiederherzustellen.

  • MSALErrorServerDeclinedScopes: Einige oder alle Bereiche wurden abgelehnt. Entscheiden Sie, ob sie nur mit den gewährten Bereichen fortfahren oder den Anmeldevorgang beenden möchten.

Note

Das MSALInternalError Enum sollte nur als Referenz und zum Debuggen verwendet werden. Versuchen Sie nicht, diese Fehler zur Laufzeit automatisch zu behandeln. Wenn ihre App auf einen der Fehler stößt, die unter MSALInternalErrorfallen, sollten Sie eine generische Meldung anzeigen, in der erläutert wird, was passiert ist.

Zum Beispiel bedeutet MSALInternalErrorBrokerResponseNotReceived, dass der Benutzer die Authentifizierung nicht abgeschlossen hat und manuell zur App zurückgekehrt ist. In diesem Fall sollte Ihre App eine generische Fehlermeldung anzeigen, in der erläutert wird, dass die Authentifizierung nicht abgeschlossen wurde, und sie schlagen vor, dass sie erneut versuchen, sich zu authentifizieren.

Im folgenden Objective-C Beispielcode werden bewährte Methoden für die Behandlung allgemeiner Fehlerbedingungen veranschaulicht.

    MSALInteractiveTokenParameters *interactiveParameters = ...;
    MSALSilentTokenParameters *silentParameters = ...;
    
    MSALCompletionBlock completionBlock;
    __block __weak MSALCompletionBlock weakCompletionBlock;
    
    weakCompletionBlock = completionBlock = ^(MSALResult *result, NSError *error)
    {
        if (!error)
        {
            // Use result.accessToken
            NSString *accessToken = result.accessToken;
            return;
        }
        
        if ([error.domain isEqualToString:MSALErrorDomain])
        {
            switch (error.code)
            {
                case MSALErrorInteractionRequired:
                {
                    // Interactive auth will be required
                    [application acquireTokenWithParameters:interactiveParameters
                                            completionBlock:weakCompletionBlock];
                    
                    break;
                }
                    
                case MSALErrorServerDeclinedScopes:
                {
                    // These are list of granted and declined scopes.
                    NSArray *grantedScopes = error.userInfo[MSALGrantedScopesKey];
                    NSArray *declinedScopes = error.userInfo[MSALDeclinedScopesKey];
                    
                    // To continue acquiring token for granted scopes only, do the following
                    silentParameters.scopes = grantedScopes;
                    [application acquireTokenSilentWithParameters:silentParameters
                                                  completionBlock:weakCompletionBlock];
                    
                    // Otherwise, instead, handle error fittingly to the application context
                    break;
                }
                    
                case MSALErrorServerProtectionPoliciesRequired:
                {
                    // Integrate the Intune SDK and call the
                    // remediateComplianceForIdentity:silent: API.
                    // Handle this error only if you integrated Intune SDK.
                    // See more info here: https://aka.ms/intuneMAMSDK
                    
                    break;
                }
                    
                case MSALErrorUserCanceled:
                {
                    // The user cancelled the web auth session.
                    // You may want to ask the user to try again.
                    // Handling of this error is optional.
                    
                    break;
                }
                    
                case MSALErrorInternal:
                {
                    // Log the error, then inspect the MSALInternalErrorCodeKey
                    // in the userInfo dictionary.
                    // Display generic error message to the end user
                    // More detailed information about the specific error
                    // under MSALInternalErrorCodeKey can be found in MSALInternalError enum.
                    NSLog(@"Failed with error %@", error);
                    
                    break;
                }
                    
                default:
                    NSLog(@"Failed with unknown MSAL error %@", error);
                    
                    break;
            }
            
            return;
        }
        
        // Handle no internet connection.
        if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorNotConnectedToInternet)
        {
            NSLog(@"No internet connection.");
            return;
        }
        
        // Other errors may require trying again later,
        // or reporting authentication problems to the user.
        NSLog(@"Failed with error %@", error);
    };
    
    // Acquire token silently
    [application acquireTokenSilentWithParameters:silentParameters
                                  completionBlock:completionBlock];

     // or acquire it interactively.
     [application acquireTokenWithParameters:interactiveParameters
                             completionBlock:completionBlock];
    let interactiveParameters: MSALInteractiveTokenParameters = ...
    let silentParameters: MSALSilentTokenParameters = ...
            
    var completionBlock: MSALCompletionBlock!
    completionBlock = { (result: MSALResult?, error: Error?) in
                
        if let result = result
        {
            // Use result.accessToken
            let accessToken = result.accessToken
            return
        }

        guard let error = error as NSError? else { return }

        if error.domain == MSALErrorDomain, let errorCode = MSALError(rawValue: error.code)
        {
            switch errorCode
            {
                case .interactionRequired:
                    // Interactive auth will be required
                    application.acquireToken(with: interactiveParameters, completionBlock: completionBlock)

                case .serverDeclinedScopes:
                    let grantedScopes = error.userInfo[MSALGrantedScopesKey]
                    let declinedScopes = error.userInfo[MSALDeclinedScopesKey]

                    if let scopes = grantedScopes as? [String] {
                        silentParameters.scopes = scopes
                        application.acquireTokenSilent(with: silentParameters, completionBlock: completionBlock)
                    }
                        
                    case .serverProtectionPoliciesRequired:
                        // Integrate the Intune SDK and call the
                        // remediateComplianceForIdentity:silent: API.
                        // Handle this error only if you integrated Intune SDK.
                        // See more info here: https://aka.ms/intuneMAMSDK
                        break
                        
                    case .userCanceled:
                       // The user cancelled the web auth session.
                       // You may want to ask the user to try again.
                       // Handling of this error is optional.
                       break
                        
                    case .internal:
                        // Log the error, then inspect the MSALInternalErrorCodeKey
                        // in the userInfo dictionary.
                        // Display generic error message to the end user
                        // More detailed information about the specific error
                        // under MSALInternalErrorCodeKey can be found in MSALInternalError enum.
                        print("Failed with error \(error)");
                        
                    default:
                        print("Failed with unknown MSAL error \(error)")
            }
        }
                
        // Handle no internet connection.
        if error.domain == NSURLErrorDomain && error.code == NSURLErrorNotConnectedToInternet
        {
            print("No internet connection.")
            return
        }
                
        // Other errors may require trying again later,
        // or reporting authentication problems to the user.
        print("Failed with error \(error)");    
    }
   
    // Acquire token silently
    application.acquireToken(with: interactiveParameters, completionBlock: completionBlock)
 
    // or acquire it interactively.
    application.acquireTokenSilent(with: silentParameters, completionBlock: completionBlock)

Herausforderungen für bedingten Zugriff und Ansprüche

Beim stillen Abrufen von Token kann bei Ihrer Anwendung ein Fehler auftreten, wenn eine API, auf die Sie zugreifen möchten, eine Anspruchsanforderung für den bedingten Zugriff erfordert, z. B. eine MFA-Richtlinie.

Das Muster für die Behandlung dieses Fehlers besteht darin, ein Token mithilfe von MSAL interaktiv abzurufen. Dadurch wird der Benutzer aufgefordert und erhält die Möglichkeit, die erforderliche Richtlinie für bedingten Zugriff zu erfüllen.

In bestimmten Fällen können Sie beim Aufruf einer API, die bedingten Zugriff erfordert, in dem von der API ausgegebenen Fehler eine Anspruchsaufforderung erhalten. Wenn beispielsweise die Richtlinie für den bedingten Zugriff über ein verwaltetes Gerät (Intune) verfügt, ist der Fehler etwa AADSTS53000: Ihr Gerät muss verwaltet werden, um auf diese Ressource oder etwas ähnliches zuzugreifen. In diesem Fall können Sie die Ansprüche im Aufruf für den Tokenabruf übergeben, damit der Benutzer aufgefordert wird, die entsprechende Richtlinie zu erfüllen.

MSAL für iOS und macOS ermöglicht es Ihnen, bestimmte Ansprüche sowohl in interaktiven als auch in automatischen Tokenabrufszenarien anzufordern.

Um benutzerdefinierte Claims anzufordern, geben Sie claimsRequest in MSALSilentTokenParameters oder MSALInteractiveTokenParameters an.

Weitere Informationen finden Sie unter Anfordern benutzerdefinierter Ansprüche mit MSAL für iOS und macOS.

Wiederholen nach Fehlern und Ausnahmen

Es wird erwartet, dass Sie beim Aufrufen von MSAL eigene Wiederholungsrichtlinien implementieren. MSAL führt HTTP-Aufrufe an den Microsoft Entra Dienst aus, und gelegentlich können Fehler auftreten. Beispielsweise kann das Netzwerk nach unten gehen oder der Server überlastet ist.

HTTP 429

Wenn der Diensttokenserver (Service Token Server, STS) mit zu vielen Anfragen überlastet ist, gibt er den HTTP-Fehler 429 mit einem Hinweis darauf zurück, wann Sie es im Antwortfeld Retry-After erneut versuchen können.

Nächste Schritte

Erwägen Sie, die Protokollierung in MSAL für iOS/macOS zu aktivieren, um Probleme zu diagnostizieren und zu debuggen.