Przewodnik migracji biblioteki ADAL do biblioteki MSAL dla systemu Android

W tym artykule przedstawiono zmiany, które należy wprowadzić w celu przeprowadzenia migracji aplikacji korzystającej z biblioteki Azure Active Directory Authentication Library (ADAL) do korzystania z biblioteki Microsoft Authentication Library (MSAL).

Wyróżnianie różnic

Biblioteka ADAL współpracuje z punktem końcowym usługi Azure AD w wersji 1.0. Biblioteka Microsoft Authentication Library (MSAL) współpracuje z Platforma tożsamości Microsoft, wcześniej znaną jako punkt końcowy usługi Azure AD w wersji 2.0. W Platforma tożsamości Microsoft różni się ona od usługi Azure AD w wersji 1.0:

Obsługuje:

  • Tożsamość organizacyjna (Microsoft Entra ID)

  • Tożsamości inne niż organizacyjne, takie jak Outlook.com, Xbox Live itd.

  • (Tylko usługa Azure AD B2C) Logowanie federacyjne przy użyciu usług Google, Facebook, Twitter i Amazon

  • Czy standardy są zgodne z:

    • Protokół OAuth w wersji 2.0
    • Połączenie OpenID (OIDC)

Publiczny interfejs API biblioteki MSAL wprowadza ważne zmiany, w tym:

  • Nowy model uzyskiwania dostępu do tokenów:
    • Biblioteka ADAL zapewnia dostęp do tokenów za pośrednictwem AuthenticationContextelementu , który reprezentuje serwer. Biblioteka MSAL zapewnia dostęp do tokenów za pośrednictwem PublicClientApplicationelementu , który reprezentuje klienta. Deweloperzy klienta nie muszą tworzyć nowego PublicClientApplication wystąpienia dla każdego urzędu, z którego muszą korzystać. Wymagana jest tylko jedna PublicClientApplication konfiguracja.
    • Obsługa żądania tokenów dostępu przy użyciu zakresów oprócz identyfikatorów zasobów.
    • Obsługa zgody przyrostowej. Deweloperzy mogą żądać zakresów, ponieważ użytkownik uzyskuje dostęp do coraz większej liczby funkcji w aplikacji, w tym tych, które nie zostały uwzględnione podczas rejestracji aplikacji.
    • Władze nie są już weryfikowane w czasie wykonywania. Zamiast tego deweloper deklaruje listę "znanych władz" podczas opracowywania.
  • Zmiany interfejsu API tokenu:
    • W usłudze ADAL AcquireToken() najpierw wysyła żądanie dyskretne. Niepowodzenie to powoduje wysłanie żądania interakcyjnego. To zachowanie spowodowało, że niektórzy deweloperzy polegali tylko na AcquireTokensystemie , co spowodowało nieoczekiwane wyświetlenie monitu o poświadczenia przez użytkownika. Biblioteka MSAL wymaga, aby deweloperzy mogli być celowi w przypadku otrzymania monitu interfejsu użytkownika.
      • AcquireTokenSilent zawsze powoduje dyskretne żądanie, które kończy się powodzeniem lub niepowodzeniem.
      • AcquireToken zawsze powoduje żądanie, które monituje użytkownika za pośrednictwem interfejsu użytkownika.
  • Biblioteka MSAL obsługuje logowanie z domyślnej przeglądarki lub osadzonego widoku internetowego:
    • Domyślnie jest używana domyślna przeglądarka na urządzeniu. Dzięki temu biblioteka MSAL może używać stanu uwierzytelniania (plików cookie), które mogą być już obecne dla co najmniej jednego zalogowanego konta. Jeśli nie ma stanu uwierzytelniania, uwierzytelnianie podczas autoryzacji za pośrednictwem biblioteki MSAL powoduje utworzenie stanu uwierzytelniania (plików cookie) z korzyścią dla innych aplikacji internetowych, które będą używane w tej samej przeglądarce.
  • Nowy model wyjątku:
    • Wyjątki bardziej wyraźnie definiują typ błędu, który wystąpił i co deweloper musi zrobić, aby go rozwiązać.
  • Biblioteka MSAL obsługuje obiekty parametrów dla AcquireToken wywołań i .AcquireTokenSilent
  • Biblioteka MSAL obsługuje konfigurację deklaracyjną dla:
    • Identyfikator klienta, identyfikator URI przekierowania.
    • Przeglądarka osadzona a domyślna
    • Władze
    • Ustawienia protokołu HTTP, takie jak limit czasu odczytu i połączenia

Rejestracja i migracja aplikacji do biblioteki MSAL

Nie musisz zmieniać istniejącej rejestracji aplikacji, aby używać biblioteki MSAL. Jeśli chcesz skorzystać z przyrostowej/progresywnej zgody, może być konieczne przejrzenie rejestracji w celu zidentyfikowania określonych zakresów, których chcesz zażądać przyrostowo. Więcej informacji na temat zakresów i zgody przyrostowej znajduje się poniżej.

W rejestracji aplikacji w portalu zostanie wyświetlona karta Uprawnienia interfejsu API. Zapewnia to listę interfejsów API i uprawnień (zakresów), do których aplikacja jest obecnie skonfigurowana do żądania dostępu. Zawiera również listę nazw zakresów skojarzonych z poszczególnymi uprawnieniami interfejsu API.

W przypadku biblioteki ADAL i punktu końcowego usługi Azure AD w wersji 1.0 użytkownik wyraża zgodę na zasoby, których są właścicielami, został udzielony podczas pierwszego użycia. W przypadku biblioteki MSAL i Platforma tożsamości Microsoft można zażądać zgody przyrostowo. Zgoda przyrostowa jest przydatna w przypadku uprawnień, które użytkownik może rozważyć wysokie uprawnienia lub może w inny sposób kwestionować, jeśli nie podano jasnego wyjaśnienia, dlaczego wymagane jest uprawnienie. W usłudze ADAL te uprawnienia mogły spowodować porzucenie logowania użytkownika do aplikacji.

Napiwek

Użyj zgody przyrostowej, aby udostępnić użytkownikom dodatkowy kontekst dotyczący tego, dlaczego aplikacja potrzebuje uprawnień.

Administratorzy organizacji mogą wyrazić zgodę na uprawnienia wymagane przez aplikację w imieniu wszystkich członków organizacji. Niektóre organizacje zezwalają tylko administratorom na wyrażanie zgody na aplikacje. Administracja zgoda wymaga uwzględnienia wszystkich uprawnień interfejsu API i zakresów używanych przez aplikację w rejestracji aplikacji.

Napiwek

Mimo że możesz zażądać zakresu przy użyciu biblioteki MSAL dla czegoś, co nie jest uwzględnione w rejestracji aplikacji, zalecamy zaktualizowanie rejestracji aplikacji w celu uwzględnienia wszystkich zasobów i zakresów, do których użytkownik może kiedykolwiek udzielić uprawnień.

Migrowanie z identyfikatorów zasobów do zakresów

Uwierzytelnianie i żądanie autoryzacji dla wszystkich uprawnień podczas pierwszego użycia

Jeśli obecnie używasz biblioteki ADAL i nie musisz używać zgody przyrostowej, najprostszym sposobem rozpoczęcia korzystania z biblioteki MSAL jest utworzenie acquireToken żądania przy użyciu nowego AcquireTokenParameter obiektu i ustawienie wartości identyfikatora zasobu.

Uwaga

Nie można ustawić zarówno zakresów, jak i identyfikatora zasobu. Próba ustawienia obu spowoduje wyświetlenie elementu IllegalArgumentException.

Spowoduje to takie samo zachowanie, którego używasz w wersji 1. Wszystkie uprawnienia żądane w rejestracji aplikacji są wymagane od użytkownika podczas pierwszej interakcji.

Uwierzytelnianie i żądanie uprawnień tylko w razie potrzeby

Aby skorzystać z zgody przyrostowej, utwórz listę uprawnień (zakresów) używanych przez aplikację z rejestracji aplikacji i organizuj je na dwie listy na podstawie:

  • Zakresy, których chcesz zażądać podczas pierwszej interakcji użytkownika z aplikacją podczas logowania.
  • Uprawnienia skojarzone z ważną funkcją aplikacji, które należy również wyjaśnić użytkownikowi.

Po zorganizowaniu zakresów należy zorganizować każdą listę zasobów (INTERFEJS API), dla których chcesz zażądać tokenu. Oprócz innych zakresów, które mają być autoryzowane przez użytkownika w tym samym czasie.

Obiekt parameters używany do żądania do biblioteki MSAL obsługuje:

  • Scope: lista zakresów, dla których chcesz zażądać autoryzacji i odebrać token dostępu.
  • ExtraScopesToConsent: Dodatkowa lista zakresów, dla których chcesz zażądać autoryzacji podczas żądania tokenu dostępu dla innego zasobu. Ta lista zakresów pozwala zminimalizować liczbę żądań autoryzacji użytkownika. Oznacza to mniej monitów o autoryzację użytkownika lub zgodę.

Migrowanie z elementu AuthenticationContext do elementu PublicClientApplications

Konstruowanie elementu PublicClientApplication

W przypadku korzystania z biblioteki MSAL należy utworzyć wystąpienie elementu PublicClientApplication. Ten obiekt modeluje tożsamość aplikacji i służy do podejmowania żądań do co najmniej jednego urzędu. Za pomocą tego obiektu skonfigurujesz tożsamość klienta, identyfikator URI przekierowania, urząd domyślny, czy używać przeglądarki urządzenia, czy osadzonego widoku internetowego, poziomu dziennika i nie tylko.

Możesz deklaratywnie skonfigurować ten obiekt przy użyciu formatu JSON, który należy podać jako plik lub przechowywać jako zasób w ramach pakietu APK.

Mimo że ten obiekt nie jest pojedynczym obiektem, jest używany Executors wewnętrznie do obsługi zarówno żądań interakcyjnych, jak i dyskretnych.

Firma-firma-firma

W usłudze ADAL każda organizacja żądającą tokenów dostępu wymaga oddzielnego wystąpienia klasy AuthenticationContext. W usłudze MSAL nie jest to już wymagane. Możesz określić urząd, z którego chcesz zażądać tokenu w ramach dyskretnego lub interakcyjnego żądania.

Migrowanie z weryfikacji urzędu do znanych urzędów

Biblioteka MSAL nie ma flagi umożliwiającej lub wyłączania walidacji urzędu. Weryfikacja urzędu jest funkcją biblioteki ADAL i w wczesnych wersjach biblioteki MSAL, która uniemożliwia kodowi żądanie tokenów od potencjalnie złośliwego urzędu. Biblioteka MSAL pobiera teraz listę urzędów znanych firmie Microsoft i scala listę z władzami określonymi w konfiguracji.

Napiwek

Jeśli jesteś użytkownikiem usługi Azure Business to Consumer (B2C), oznacza to, że nie musisz już wyłączać walidacji urzędu. Zamiast tego uwzględnij wszystkie obsługiwane zasady usługi Azure AD B2C jako urzędy w konfiguracji biblioteki MSAL.

Jeśli spróbujesz użyć urzędu, który nie jest znany firmie Microsoft i nie jest uwzględniony w konfiguracji, otrzymasz element UnknownAuthorityException.

Rejestrowanie

Teraz można deklaratywnie skonfigurować rejestrowanie w ramach konfiguracji, w następujący sposób:

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

Migrowanie z informacji o użytkowniku do konta

W biblioteki AuthenticationResult ADAL obiekt udostępnia UserInfo obiekt służący do pobierania informacji o uwierzytelnianym koncie. Termin "użytkownik", który oznaczał agenta ludzkiego lub oprogramowania, został zastosowany w sposób, który utrudniał komunikowanie się, że niektóre aplikacje obsługują jednego użytkownika (niezależnie od tego, czy jest to agent ludzki, czy programowy), który ma wiele kont.

Rozważ konto bankowe. Być może masz więcej niż jedno konto w więcej niż jednej instytucji finansowej. Po otwarciu konta (użytkownik) są wystawiane poświadczenia, takie jak karta bankomatu i numer PIN, które są używane do uzyskiwania dostępu do salda, płatności na rachunku itd. dla każdego konta. Te poświadczenia mogą być używane tylko w instytucji finansowej, która je wystawiła.

Analogicznie, podobnie jak konta w instytucji finansowej, konta w Platforma tożsamości Microsoft są dostępne przy użyciu poświadczeń. Te poświadczenia są zarejestrowane w firmie Microsoft lub wystawione przez firmę Microsoft. Lub przez firmę Microsoft w imieniu organizacji.

W przypadku, gdy Platforma tożsamości Microsoft różni się od instytucji finansowej, w tej analogii jest to, że Platforma tożsamości Microsoft zapewnia platformę, która umożliwia użytkownikowi korzystanie z jednego konta i skojarzonych poświadczeń w celu uzyskiwania dostępu do zasobów należących do wielu osób i organizacji. Przypomina to możliwość korzystania z karty wydanej przez jeden bank, w jeszcze innej instytucji finansowej. Działa to, ponieważ wszystkie omawiane organizacje korzystają z Platforma tożsamości Microsoft, co umożliwia korzystanie z jednego konta w wielu organizacjach. Oto przykład:

Sam działa w przypadku Contoso.com, ale zarządza maszynami wirtualnymi platformy Azure należącymi do Fabrikam.com. Aby Sam zarządzał maszynami wirtualnymi firmy Fabrikam, musi mieć uprawnienia dostępu do nich. Ten dostęp można udzielić, dodając konto Sam do Fabrikam.com i udzielając mu roli, która umożliwia mu pracę z maszynami wirtualnymi. Można to zrobić w witrynie Azure Portal.

Dodanie konta Contoso.com Sam jako członka Fabrikam.com spowodowałoby utworzenie nowego rekordu w identyfikatorze Microsoft Entra ID Fabrikam.com dla sam. Rekord Sam w identyfikatorze Entra firmy Microsoft jest znany jako obiekt użytkownika. W takim przypadku obiekt użytkownika wskazuje obiekt użytkownika Sam w Contoso.com. Obiekt użytkownika Fabrikam firmy Sam jest lokalną reprezentacją sam i będzie używany do przechowywania informacji o koncie skojarzonym z użytkownikiem Sam w kontekście Fabrikam.com. W Contoso.com tytuł Sam jest starszym konsultantem DevOps. W firmie Fabrikam tytuł Sam to Contractor-Virtual Machines. W Contoso.com sam nie jest odpowiedzialny ani autoryzowany do zarządzania maszynami wirtualnymi. W Fabrikam.com jest to jego jedyna funkcja pracy. Jednak Sam nadal ma tylko jeden zestaw poświadczeń do śledzenia, które są poświadczeniami wystawionymi przez Contoso.com.

Po pomyślnym acquireToken wywołaniu zostanie wyświetlone odwołanie do IAccount obiektu, którego można użyć w późniejszych acquireTokenSilent żądaniach.

IMultiTenantAccount

Jeśli masz aplikację, która uzyskuje dostęp do oświadczeń dotyczących konta z każdej dzierżawy, w której jest reprezentowane konto, możesz rzutować IAccount obiekty na IMultiTenantAccount. Ten interfejs zawiera mapę ITenantProfileselementu , z kluczem według identyfikatora dzierżawy, która umożliwia dostęp do oświadczeń należących do konta w każdej dzierżawie, z której zażądano tokenu względem bieżącego konta.

Oświadczenia w katalogu głównym elementu IAccount i IMultiTenantAccount zawsze zawierają oświadczenia z dzierżawy macierzystej. Jeśli jeszcze nie zażądano tokenu w dzierżawie głównej, ta kolekcja będzie pusta.

Inne zmiany

Korzystanie z nowego elementu AuthenticationCallback

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

Migrowanie do nowych wyjątków

W biblioteki ADAL istnieje jeden typ wyjątku, AuthenticationExceptionktóry zawiera metodę pobierania ADALError wartości wyliczenia. W bibliotekach MSAL istnieje hierarchia wyjątków, a każdy z nich ma własny zestaw skojarzonych kodów błędów.

Wyjątek opis
MsalArgumentException Zgłaszany, jeśli co najmniej jeden argument danych wejściowych jest nieprawidłowy.
MsalClientException Zgłaszany, jeśli błąd jest po stronie klienta.
MsalDeclinedScopeException Zgłaszany, jeśli co najmniej jeden żądany zakres został odrzucony przez serwer.
MsalException Domyślny sprawdzony wyjątek zgłaszany przez bibliotekę MSAL.
MsalIntuneAppProtectionPolicyRequiredException Zgłaszany, jeśli zasób ma włączone zasady ochrony MAMCA.
MsalServiceException Zgłaszany, jeśli błąd jest po stronie serwera.
MsalUiRequiredException Zgłaszany, jeśli nie można odświeżyć tokenu w trybie dyskretnym.
MsalUserCancelException Zgłaszany, jeśli użytkownik anulował przepływ uwierzytelniania.

Translacja ADALError do msalException

Jeśli przechwytujesz te błędy w biblioteki ADAL... ... przechwyć następujące wyjątki biblioteki MSAL:
Brak równoważnego błędu 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
Brak równoważnego błędu ADALError MsalDeclinedScopeException
  • ADALError.APP_PACKAGE_NAME_NOT_FOUND
  • ADALError.BROKER_APP_VERIFICATION_FAILED
  • ADALError.PACKAGE_NAME_NOT_FOUND
MsalException
Brak równoważnego błędu ADALError MsalIntuneAppProtectionPolicyRequiredException
  • ADALError.SERVER_ERROR
  • ADALError.SERVER_INVALID_REQUEST
MsalServiceException
  • ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED
MsalUiRequiredException
Brak równoważnego błędu ADALError MsalUserCancelException

Rejestrowanie biblioteki ADAL do rejestrowania biblioteki MSAL

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