Migratiehandleiding voor ADAL naar MSAL voor Android

In dit artikel worden de wijzigingen beschreven die u moet aanbrengen om een app te migreren die gebruikmaakt van de Azure Active Directory Authentication Library (ADAL) om de Microsoft Authentication Library (MSAL) te gebruiken.

Gemarkeerde verschillen

ADAL werkt met het Azure AD v1.0-eindpunt. De Microsoft Authentication Library (MSAL) werkt met de Microsoft identity platform, voorheen bekend als het Azure AD v2.0-eindpunt. Het Microsoft identity platform verschilt van Azure AD v1.0 op de volgende punten:

Ondersteunt:

  • Organisatie-identiteit (Microsoft Entra ID)

  • Niet-organisatie-identiteiten, zoals Outlook.com, Xbox Live, enzovoort

  • (alleen Azure AD B2C) Federatieve aanmelding met Google, Facebook, X en Amazon

  • Is standaarden compatibel met:

    • OAuth v2.0
    • OpenID Connect (OIDC)

De openbare MSAL-API introduceert belangrijke wijzigingen, waaronder:

  • Een nieuw model voor toegang tot tokens:
    • ADAL biedt toegang tot tokens via de AuthenticationContext, die de server vertegenwoordigt. MSAL biedt toegang tot tokens via de PublicClientApplication, die de client vertegenwoordigt. Clientontwikkelaars hoeven geen nieuw PublicClientApplication exemplaar te maken voor elke instantie waarmee ze moeten communiceren. Er is slechts één PublicClientApplication configuratie vereist.
    • Ondersteuning voor het aanvragen van toegangstokens met scopes naast resource-id's.
    • Ondersteuning voor incrementele toestemming. Ontwikkelaars kunnen machtigingen aanvragen naarmate de gebruiker toegang krijgt tot steeds meer functionaliteit in de app, waaronder machtigingen die niet zijn opgenomen bij de registratie van de app.
    • Autoriteiten worden niet meer gevalideerd tijdens runtime. In plaats daarvan declareert de ontwikkelaar een lijst met 'bekende autoriteiten' tijdens de ontwikkeling.
  • Wijzigingen in de token-API:
    • In ADAL AcquireToken() doet u eerst een stille aanvraag. Als dat niet lukt, wordt er een interactieve aanvraag ingediend. Dit gedrag leidde ertoe dat sommige ontwikkelaars uitsluitend op AcquireToken vertrouwden, waardoor de gebruiker soms onverwacht om aanmeldingsgegevens werd gevraagd. MSAL vereist dat ontwikkelaars bewust bepalen wanneer de gebruiker een UI-prompt te zien krijgt.
      • AcquireTokenSilent resulteert altijd in een stille aanvraag die slaagt of mislukt.
      • AcquireToken resulteert altijd in een verzoek waarbij de gebruiker via de gebruikersinterface om actie wordt gevraagd.
  • MSAL biedt ondersteuning voor aanmelden vanuit een standaardbrowser of een ingesloten webweergave:
    • Standaard wordt de standaardbrowser op het apparaat gebruikt. Hierdoor kan MSAL de verificatiestatus (cookies) gebruiken die mogelijk al aanwezig zijn voor een of meer aangemelde accounts. Als er geen verificatiestatus aanwezig is, resulteert verificatie tijdens autorisatie via MSAL in de verificatiestatus (cookies) die worden gemaakt ten behoeve van andere webtoepassingen die in dezelfde browser worden gebruikt.
  • Nieuw uitzonderingsmodel:
    • Uitzonderingen definiëren duidelijker het type fout dat is opgetreden en wat de ontwikkelaar moet doen om deze op te lossen.
  • MSAL ondersteunt parameterobjecten voor AcquireToken en AcquireTokenSilent aanroepen.
  • MSAL ondersteunt declaratieve configuratie voor:
    • Client-id, omleidings-URI.
    • Ingesloten versus standaardbrowser
    • Machtigingen
    • HTTP-instellingen, zoals time-out voor lezen en verbinding

Uw app-registratie en -migratie naar MSAL

U hoeft uw bestaande app-registratie niet te wijzigen om MSAL te gebruiken. Als u gebruik wilt maken van gefaseerde/progressieve toestemming, moet u mogelijk de registratie nalopen om te bepalen welke specifieke machtigingen u gefaseerd wilt aanvragen. Meer informatie over machtigingen en stapsgewijze toestemming volgt.

In de app-registratie in de portal ziet u een tabblad API-machtigingen . Dit biedt een lijst met de API's en machtigingen (bereiken) waartoe uw app momenteel is geconfigureerd om toegang aan te vragen. Het toont ook een lijst met de scopenamen die geassocieerd zijn met elke API-machtiging.

Met ADAL en het Azure AD v1.0-eindpunt heeft de gebruiker toestemming gegeven voor resources die ze bezitten bij eerste gebruik. Met MSAL en de Microsoft identity platform kunt u incrementeel toestemming aanvragen. Incrementele toestemming is handig voor machtigingen die een gebruiker kan beschouwen als een hoge bevoegdheid, of kan anderszins vragen stellen als deze niet is opgegeven met een duidelijke uitleg van waarom de machtiging is vereist. In ADAL kunnen deze machtigingen ertoe leiden dat de gebruiker zich niet meer aanmeldt bij uw app.

Tip

Gebruik incrementele toestemming om uw gebruikers aanvullende context te bieden over waarom uw app een machtiging nodig heeft.

Organisatiebeheerders kunnen toestemming geven voor machtigingen die uw toepassing vereist namens alle leden van hun organisatie. Sommige organisaties staan alleen beheerders toe om toestemming te geven voor toepassingen. Beheerderstoestemming vereist dat u alle API-machtigingen en -bereiken opneemt die worden gebruikt door uw toepassing in uw app-registratie.

Tip

Hoewel u via MSAL een scope kunt aanvragen die niet in uw app-registratie is opgenomen, raden we u aan uw app-registratie bij te werken zodat deze alle resources en machtigingsbereiken bevat waarvoor een gebruiker ooit toestemming zou kunnen verlenen.

Migreren van resource-id's naar scopes

Verificatie en autorisatie aanvragen voor alle machtigingen voor het eerste gebruik

Als u momenteel gebruikmaakt van ADAL en u geen incrementele toestemming hoeft te gebruiken, is de eenvoudigste manier om MSAL te gaan gebruiken om een acquireToken aanvraag te doen met behulp van het nieuwe AcquireTokenParameter object en de waarde van de resource-id in te stellen.

Caution

Het is niet mogelijk om zowel scopes als een resource-id in te stellen. Wanneer u beide probeert in te stellen, resulteert dat in een IllegalArgumentException.

Dit resulteert in hetzelfde v1-gedrag dat u gebruikt. Alle machtigingen die zijn aangevraagd in uw app-registratie, worden tijdens hun eerste interactie door de gebruiker aangevraagd.

Machtigingen alleen verifiëren en aanvragen als dat nodig is

Als u wilt profiteren van incrementele toestemming, maakt u een lijst met machtigingen (bereiken) die uw app gebruikt vanuit uw app-registratie en organiseert u deze in twee lijsten op basis van:

  • Welke machtigingen u wilt aanvragen wanneer de gebruiker zich voor het eerst aanmeldt bij uw app.
  • De machtigingen die zijn gekoppeld aan een belangrijke functie van uw app die u ook moet uitleggen aan de gebruiker.

Zodra u de machtigingen hebt georganiseerd, rangschikt u elke lijst op basis van de resource (API) waarvoor u een token wilt aanvragen. En alle andere scopes die u wilt dat de gebruiker tegelijkertijd machtigt.

Het parameterobject dat wordt gebruikt om uw aanvraag naar MSAL te verzenden, ondersteunt:

  • Scope: De lijst met machtigingsbereiken waarvoor u machtiging wilt aanvragen en een toegangstoken wilt ontvangen.
  • ExtraScopesToConsent: Een aanvullende lijst met machtigingen waarvoor u toestemming wilt aanvragen terwijl u een toegangstoken voor een andere bron aanvraagt. Met deze lijst met scopes kunt u het aantal keren beperken dat u autorisatie van de gebruiker hoeft aan te vragen. Dit betekent minder gebruikersautorisatie- of toestemmingsprompts.

Migreren van AuthenticationContext naar PublicClientApplications

PublicClientApplication maken

Wanneer u MSAL gebruikt, instantieert u een PublicClientApplication. Dit object modelleert uw app-identiteit en wordt gebruikt om aanvragen te doen bij een of meer autoriteiten. Met dit object configureert u uw clientidentiteit, omleidings-URI, standaardinstantie, of u de apparaatbrowser wilt gebruiken versus ingesloten webweergave, het logboekniveau en meer.

U kunt dit object declaratief configureren met JSON, die u als een bestand opgeeft of als een resource in uw APK opslaat.

Hoewel dit object geen singleton is, wordt intern gebruikgemaakt van gedeelde Executors aanvragen voor interactieve en stille aanvragen.

Business to Business

In ADAL vereist elke organisatie van wie u toegangstokens aanvraagt een afzonderlijk exemplaar van de AuthenticationContext. In MSAL is dit geen vereiste meer. U kunt de instantie opgeven waaruit u een token wilt aanvragen als onderdeel van uw stille of interactieve aanvraag.

Migreren van autorisatievalidatie naar bekende autoriteiten

MSAL heeft geen vlag om autorisatievalidatie in of uit te schakelen. Autorisatievalidatie is een functie in ADAL en in de vroege releases van MSAL voorkomt u dat uw code tokens aanvraagt bij een mogelijk schadelijke instantie. MSAL haalt nu een lijst met autoriteiten op die bekend zijn bij Microsoft en voegt deze lijst samen met de autoriteiten die u in uw configuratie hebt opgegeven.

Tip

Als u een Azure B2C-gebruiker (Business to Consumer) bent, betekent dit dat u autorisatievalidatie niet meer hoeft uit te schakelen. Neem in plaats daarvan elk van uw ondersteunde Azure AD B2C-beleidsregels op als instanties in uw MSAL-configuratie. Houd er rekening mee dat vanaf 1 mei 2025 Azure AD B2C niet meer beschikbaar is voor aankoop door nieuwe klanten. Zie Is Azure AD B2C nog steeds beschikbaar om te kopen? in onze veelgestelde vragen voor meer informatie.

Als u probeert een instantie te gebruiken die niet bekend is bij Microsoft en niet is opgenomen in uw configuratie, krijgt u een UnknownAuthorityException.

Logging

U kunt nu declaratief logboekregistratie configureren als onderdeel van uw configuratie, zoals hieronder:

"logging": {
  "pii_enabled": false,
  "log_level": "WARNING",
  "logcat_enabled": true
}

Migreren van UserInfo naar Account

In ADAL biedt het AuthenticationResult een UserInfo object dat wordt gebruikt om informatie over het geverifieerde account op te halen. De term 'gebruiker', wat een menselijke of softwareagent betekende, werd toegepast op een manier die het moeilijk maakte om te communiceren dat sommige apps één gebruiker ondersteunen (of een menselijke of softwareagent) meerdere accounts heeft.

Denk aan een bankrekening. Mogelijk hebt u meer dan één rekening bij meer dan één financiële instelling. Wanneer u een account opent, krijgt u (de gebruiker) referenties, zoals een ATM Card &pin, die worden gebruikt voor toegang tot uw saldo, factuurbetalingen, enzovoort, voor elke rekening. Deze referenties kunnen alleen worden gebruikt bij de financiële instelling die ze heeft uitgegeven.

Naar analogie, zoals rekeningen bij een financiële instelling, worden rekeningen in de Microsoft identity platform geopend met behulp van referenties. Deze referenties worden geregistreerd bij of uitgegeven door Microsoft. Of door Microsoft namens een organisatie.

Wanneer de Microsoft identity platform verschilt van een financiële instelling, is het in deze analogie dat de Microsoft identity platform een kader biedt waarmee een gebruiker één account en de bijbehorende referenties kan gebruiken voor toegang tot resources die deel uitmaken van meerdere personen en organisaties. Dit is vergelijkbaar met het gebruik van een kaart die door de ene bank is uitgegeven, bij een andere financiële instelling. Dit werkt omdat alle betrokken organisaties de Microsoft identity platform gebruiken, waardoor één account in meerdere organisaties kan worden gebruikt. Hier is een voorbeeld:

Sam werkt voor Contoso.com, maar beheert Azure virtuele machines die deel uitmaken van Fabrikam.com. Sam moet gemachtigd zijn om toegang te krijgen tot de virtuele machines van Fabrikam. Deze toegang kan worden verleend door Sam's account toe te voegen aan Fabrikam.com en zijn account een rol te geven waarmee hij met de virtuele machines kan werken. Dit zou gebeuren met de Azure portal.

Als u sam's Contoso.com-account toevoegt als lid van Fabrikam.com, wordt er een nieuwe record gemaakt in de Microsoft Entra ID van Fabrikam.com voor Sam. De record van Sam in Microsoft Entra ID wordt een gebruikersobject genoemd. In dit geval wijst dat gebruikersobject terug naar het gebruikersobject van Sam in Contoso.com. Het Fabrikam-gebruikersobject van Sam is de lokale weergave van Sam en wordt gebruikt voor het opslaan van informatie over het account dat is gekoppeld aan Sam in de context van Fabrikam.com. In Contoso.com is Sam's titel Senior DevOps Consultant. In Fabrikam is Sam's functietitel Contractor-Virtual Machines. In Contoso.com is Sam niet verantwoordelijk of gemachtigd om virtuele machines te beheren. In Fabrikam.com is dat zijn enige functie. Maar Sam heeft nog maar één set referenties om bij te houden. Dit zijn de referenties die zijn uitgegeven door Contoso.com.

Zodra een geslaagde acquireToken aanroep is gedaan, ziet u een verwijzing naar een IAccount object dat in latere acquireTokenSilent aanvragen kan worden gebruikt.

IMultiTenantAccount

Als u een app heeft die toegang heeft tot claims over een account van elk van de tenants waarin het account is vertegenwoordigd, kunt u objecten van het type IAccount casten naar IMultiTenantAccount. Deze interface biedt een kaart van ITenantProfiles, gesleuteld op tenant-id, waarmee u toegang hebt tot de claims die deel uitmaken van het account in elk van de tenants waarvan u een token hebt aangevraagd ten opzichte van het huidige account.

De claims aan de basis van de IAccount en IMultiTenantAccount bevatten altijd de claims van de basistenant. Als u nog geen aanvraag hebt ingediend voor een token binnen de tenant thuis, is deze verzameling leeg.

Andere wijzigingen

De nieuwe AuthenticationCallback gebruiken

// Existing ADAL Interface
public interface AuthenticationCallback<T> {

    /**
     * This will have the token info.
     *
     * @param result returns <T>
     */
    void onSuccess(T result);

    /**
     * Sends error information. This can be user related error or server error.
     * Cancellation error is AuthenticationCancelError.
     *
     * @param exc return {@link Exception}
     */
    void onError(Exception exc);
}
// New Interface for Interactive AcquireToken
public interface AuthenticationCallback {

    /**
     * Authentication finishes successfully.
     *
     * @param authenticationResult {@link IAuthenticationResult} that contains the success response.
     */
    void onSuccess(final IAuthenticationResult authenticationResult);

    /**
     * Error occurs during the authentication.
     *
     * @param exception The {@link MsalException} contains the error code, error message and cause if applicable. The exception
     *                  returned in the callback could be {@link MsalClientException}, {@link MsalServiceException}
     */
    void onError(final MsalException exception);

    /**
     * Will be called if user cancels the flow.
     */
    void onCancel();
}

// New Interface for Silent AcquireToken
public interface SilentAuthenticationCallback {

    /**
     * Authentication finishes successfully.
     *
     * @param authenticationResult {@link IAuthenticationResult} that contains the success response.
     */
    void onSuccess(final IAuthenticationResult authenticationResult);

    /**
     * Error occurs during the authentication.
     *
     * @param exception The {@link MsalException} contains the error code, error message and cause if applicable. The exception
     *                  returned in the callback could be {@link MsalClientException}, {@link MsalServiceException} or
     *                  {@link MsalUiRequiredException}.
     */
    void onError(final MsalException exception);
}

Migreren naar de nieuwe uitzonderingen

In ADAL is er één type uitzondering, AuthenticationExceptiondat een methode bevat voor het ophalen van de ADALError enum-waarde. In MSAL is er een hiërarchie van uitzonderingen en elk heeft een eigen set gekoppelde specifieke foutcodes.

Exception Description
MsalArgumentException Wordt gegenereerd als een of meer invoerargumenten ongeldig zijn.
MsalClientException Wordt opgeworpen als de fout aan de clientzijde optreedt.
MsalDeclinedScopeException Wordt gegenereerd als een of meer gevraagde scopes door de server zijn geweigerd.
MsalException Standaard gecontroleerde uitzondering die door MSAL wordt gegenereerd.
MsalIntuneAppProtectionPolicyRequiredException Wordt gegenereerd wanneer voor de resource het MAMCA-beveiligingsbeleid is ingeschakeld.
MsalServiceException Wordt gegenereerd als de fout zich aan de serverzijde bevindt.
MsalUiRequiredException Opgeworpen als het token niet stilzwijgend kan worden vernieuwd.
MsalUserCancelException Opgeworpen als de gebruiker de authenticatiestroom heeft geannuleerd.

ADALError naar MsalException-vertaling

Als u deze fouten in ADAL tegenkomt... ... handel deze MSAL-uitzonderingen af:
Geen gelijkwaardige ADALError MsalArgumentException
  • ADALError.ANDROIDKEYSTORE_FAILED
  • ADALError.AUTH_FAILED_USER_MISMATCH
  • ADALError.DECRYPTION_FAILED
  • ADALError.DEVELOPER_AUTHORITY_CAN_NOT_BE_VALIDED
  • ADALError.DEVELOPER_AUTHORITY_IS_NOT_VALID_INSTANCE
  • ADALError.DEVELOPER_AUTHORITY_IS_NOT_VALID_URL
  • ADALError.DEVICE_CONNECTION_IS_NOT_AVAILABLE
  • ADALError.DEVICE_NO_SUCH_ALGORITHM
  • ADALError.ENCODING_IS_NOT_SUPPORTED
  • ADALError.ENCRYPTION_ERROR
  • ADALError.IO_EXCEPTION
  • ADALError.JSON_PARSE_ERROR
  • ADALError.NO_NETWORK_CONNECTION_POWER_OPTIMIZATION
  • ADALError.SOCKET_TIMEOUT_EXCEPTION
MsalClientException
Geen overeenkomende ADALError MsalDeclinedScopeException
  • ADALError.APP_PACKAGE_NAME_NOT_FOUND
  • ADALError.BROKER_APP_VERIFICATION_FAILED
  • ADALError.PACKAGE_NAME_NOT_FOUND
MsalException
Geen overeenkomstige ADALError MsalIntuneAppProtectionPolicyRequiredException
  • ADALError.SERVER_ERROR
  • ADALError.SERVER_INVALID_REQUEST
MsalServiceException
  • ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED
MsalUiRequiredException
Geen overeenkomstige ADALError MsalUserCancelException

ADAL-logging naar MSAL-logging

// Legacy Interface
    StringBuilder logs = new StringBuilder();
    Logger.getInstance().setExternalLogger(new ILogger() {
            @Override
            public void Log(String tag, String message, String additionalMessage, LogLevel logLevel, ADALError errorCode) {
                logs.append(message).append('\n');
            }
        });
// New interface
  StringBuilder logs = new StringBuilder();
  Logger.getInstance().setExternalLogger(new ILoggerCallback() {
      @Override
      public void log(String tag, Logger.LogLevel logLevel, String message, boolean containsPII) {
          logs.append(message).append('\n');
      }
  });

// New Log Levels:
public enum LogLevel
{
    /**
     * Error level logging.
     */
    ERROR,
    /**
     * Warning level logging.
     */
    WARNING,
    /**
     * Info level logging.
     */
    INFO,
    /**
     * Verbose level logging.
     */
    VERBOSE
}