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).

Najważniejsze różnice

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

Obsługuje:

  • Tożsamość organizacyjna (Azure Active Directory)

  • 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
    • OpenID Connect (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 elementu AuthenticationContext, 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 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 biblioteki ADAL AcquireToken() najpierw wysyła żądanie dyskretne. Niepowodzenie to powoduje wysłanie interakcyjnego żądania. To zachowanie spowodowało, że niektórzy deweloperzy polegają tylko na AcquireTokensystemie , co spowodowało nieoczekiwane wyświetlenie monitu o podanie poświadczeń przez użytkownika. Biblioteka MSAL wymaga, aby deweloperzy mogli być celowi w przypadku otrzymania przez użytkownika monitu o interfejs użytkownika.
      • AcquireTokenSilent zawsze powoduje dyskretne żądanie, które zakończy się powodzeniem lub niepowodzeniem.
      • AcquireToken zawsze powoduje wyświetlenie żądania, 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) w celu uzyskania korzyści z innych aplikacji internetowych, które będą używane w tej samej przeglądarce.
  • Nowy model wyjątku:
    • Wyjątki wyraźniej 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 następujących elementów:
    • 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 w celu korzystania z biblioteki MSAL. Jeśli chcesz skorzystać z zgody przyrostowej/progresywnej, może być konieczne przejrzenie rejestracji w celu zidentyfikowania określonych zakresów, które chcesz zażądać przyrostowo. Więcej informacji na temat zakresów i zgody przyrostowej następuje.

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 użytkownik wyraża zgodę na zasoby, których są właścicielami, zostały przyznane podczas pierwszego użycia. W przypadku biblioteki MSAL i platformy tożsamości firmy Microsoft można żądać zgody przyrostowo. Zgoda przyrostowa jest przydatna w przypadku uprawnień, które użytkownik może rozważyć wysokie uprawnienia lub w przeciwnym razie może 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.

Porada

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

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

Porada

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ń w pierwszym użyciu

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

Przestroga

Nie można ustawić zarówno zakresów, jak i identyfikatora zasobu. Próba ustawienia obu spowoduje wystąpienie 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 porządkuj je na dwie listy na podstawie:

  • Zakresy, które 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ę według zasobu (API), dla którego chcesz zażądać tokenu. Oprócz innych zakresów, które użytkownik chce autoryzować 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 otrzymać token dostępu.
  • ExtraScopesToConsent: Dodatkowa lista zakresów, dla których chcesz zażądać autoryzacji, podczas gdy żądasz 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 utworzysz 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 za pomocą formatu JSON, który należy podać jako plik lub przechowywać jako zasób w pliku APK.

Chociaż ten obiekt nie jest pojedynczym obiektem, jest używany Executors wewnętrznie do obsługi żądań interakcyjnych i dyskretnych.

Business to Business

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

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

Biblioteka MSAL nie ma flagi, aby włączyć lub wyłączyć walidację 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 urzędami określonymi w konfiguracji.

Porada

Jeśli jesteś użytkownikiem usługi Azure Business to Consumer (B2C), oznacza to, że nie musisz już wyłączać weryfikacji urzędu. Zamiast tego uwzględnij każdą z obsługiwanych zasad usługi Azure AD B2C jako urzędów w konfiguracji biblioteki MSAL.

Jeśli próbujesz użyć urzędu, który nie jest znany firmie Microsoft i nie jest uwzględniony w konfiguracji, otrzymasz polecenie 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 elementu UserInfo do konta

W biblioteki ADAL obiekt AuthenticationResult służy UserInfo do pobierania informacji o uwierzytelnianym koncie. Termin "użytkownik", który oznaczał człowieka lub agenta 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 osoba lub agent oprogramowania), 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 numer PIN karty & bankomatu, które są używane do uzyskiwania dostępu do salda, płatności rachunku itd. dla każdego konta. Te poświadczenia mogą być używane tylko w instytucji finansowej, która je wydała.

Analogicznie, podobnie jak konta w instytucji finansowej, konta na platformie 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.

Jeśli platforma tożsamości firmy Microsoft różni się od instytucji finansowej, w tej analogii, platforma tożsamości firmy Microsoft udostępnia platformę tożsamości firmy Microsoft, która umożliwia użytkownikowi korzystanie z jednego konta i skojarzonych poświadczeń w celu uzyskania dostępu do zasobów należących do wielu osób i organizacji. To jest jak możliwość korzystania z karty wydanej przez jeden bank, w jeszcze innej instytucji finansowej. Działa to, ponieważ wszystkie organizacje, których dotyczą, korzystają z platformy tożsamości firmy Microsoft, która 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 przyznać, dodając konto Sama do Fabrikam.com i udzielając mu roli, która umożliwia mu pracę z maszynami wirtualnymi. Zostanie to zrobione w witrynie Azure Portal.

Dodanie konta Contoso.com Sam jako członka Fabrikam.com spowoduje utworzenie nowego rekordu w usłudze Azure Active Directory dla firmy Fabrikam.com dla sam. Rekord Sam w usłudze Azure Active Directory jest znany jako obiekt użytkownika. W takim przypadku obiekt użytkownika wskaże 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 Samem w kontekście Fabrikam.com. W Contoso.com tytuł Sam jest starszym konsultantem DevOps. W firmie Fabrikam tytuł Sama 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 kolejnych 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 udostępnia mapę elementu ITenantProfiles, 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 głównej. Jeśli jeszcze nie wykonano żądania 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 usłudze MSAL istnieje hierarchia wyjątków, a każdy z nich ma własny zestaw skojarzonych określonych kodów błędów.

Wyjątek Opis
MsalArgumentException Zgłaszany, jeśli co najmniej jeden argument wejściowy 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 token nie może być odświeżany w trybie dyskretnym.
MsalUserCancelException Zgłaszany, jeśli użytkownik anulował przepływ uwierzytelniania.

Tłumaczenie ADALError na 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
}