Hantera fel och undantag i MSAL för iOS/macOS

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 för iOS/macOS

Den fullständiga listan över MSAL-fel för iOS och macOS finns i uppräkningen MSALError.

Alla MSAL-producerade fel returneras med MSALErrorDomain domänen.

För systemfel returnerar MSAL originalet NSError från system-API:et. Om tokenförvärvet till exempel misslyckas på grund av bristande nätverksanslutning returnerar MSAL ett fel med domänen NSURLErrorDomain och NSURLErrorNotConnectedToInternet koden.

Vi rekommenderar att du hanterar minst följande två MSAL-fel på klientsidan:

  • MSALErrorInteractionRequired: Användaren måste göra en interaktiv begäran. Det finns många villkor som kan leda till det här felet, till exempel en autentiseringssession som har upphört att gälla eller behovet av ytterligare autentiseringskrav. Anropa API:et för interaktiv tokenhämtning i MSAL för att återställa.

  • MSALErrorServerDeclinedScopes: Vissa eller alla behörigheter avslogs. Bestäm om du bara vill fortsätta med de beviljade omfången eller stoppa inloggningsprocessen.

Note

MSALInternalError-enumen bör endast användas som referens och för felsökning. Försök inte att automatiskt hantera dessa fel vid körning. Om din app stöter på något av de fel som faller under MSALInternalErrorkanske du vill visa ett allmänt meddelande som förklarar vad som hände.

Det innebär till exempel MSALInternalErrorBrokerResponseNotReceived att användaren inte slutförde autentiseringen och manuellt returnerade till appen. I det här fallet bör appen visa ett allmänt felmeddelande som förklarar att autentiseringen inte slutfördes och föreslå att de försöker autentisera igen.

Följande Objective-C exempelkod visar metodtips för att hantera några vanliga feltillstånd.

    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)

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.

MED MSAL för iOS och macOS kan du begära specifika anspråk i både interaktiva och tysta tokenanskaffningsscenarier.

Om du vill begära anpassade anspråk anger du claimsRequest i MSALSilentTokenParameters eller MSALInteractiveTokenParameters.

Mer information finns i Begära anpassade anspråk med MSAL för iOS och macOS .

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 .

Nästa steg

Överväg att aktivera loggning i MSAL för iOS/macOS för att hjälpa dig att diagnostisera och felsöka problem.