Guia de migração ADAL para MSAL para Android

Este artigo destaca as alterações que você precisa fazer para migrar um aplicativo que usa a Biblioteca de Autenticação do Ative Directory do Azure (ADAL) para usar a Biblioteca de Autenticação da Microsoft (MSAL).

Destaques da diferença

A ADAL funciona com o ponto de extremidade do Azure AD v1.0. A Biblioteca de Autenticação da Microsoft (MSAL) funciona com a plataforma de identidade da Microsoft, anteriormente conhecida como ponto de extremidade do Azure AD v2.0. A plataforma de identidade da Microsoft difere do Azure AD v1.0 porque:

Suporta:

  • Identidade Organizacional (Microsoft Entra ID)

  • Identidades não organizacionais, como Outlook.com, Xbox Live e assim por diante

  • (Apenas Azure AD B2C) Login federado com Google, Facebook, Twitter e Amazon

  • As normas são compatíveis com:

    • OAuth v2.0
    • Conexão OpenID (OIDC)

A API pública MSAL introduz alterações importantes, incluindo:

  • Um novo modelo para acessar tokens:
    • A ADAL fornece acesso a tokens através do AuthenticationContext, que representa o servidor. A MSAL fornece acesso a tokens através do PublicClientApplication, que representa o cliente. Os desenvolvedores clientes não precisam criar uma nova PublicClientApplication instância para cada Autoridade com a qual precisam interagir. Apenas uma PublicClientApplication configuração é necessária.
    • Suporte para solicitar tokens de acesso usando escopos, além de identificadores de recursos.
    • Suporte para consentimento incremental. Os desenvolvedores podem solicitar escopos à medida que o usuário acessa mais e mais funcionalidades no aplicativo, incluindo aquelas não incluídas durante o registro do aplicativo.
    • As autoridades já não são validadas em tempo de execução. Em vez disso, o desenvolvedor declara uma lista de "autoridades conhecidas" durante o desenvolvimento.
  • Alterações na API do token:
    • Na ADAL, AcquireToken() primeiro faz um pedido silencioso. Caso contrário, faz um pedido interativo. Esse comportamento resultou em alguns desenvolvedores confiando apenas no AcquireToken, o que resultou no usuário sendo solicitado inesperadamente para credenciais às vezes. O MSAL exige que os desenvolvedores sejam intencionais sobre quando o usuário recebe um prompt de interface do usuário.
      • AcquireTokenSilent sempre resulta em uma solicitação silenciosa que é bem-sucedida ou falha.
      • AcquireToken sempre resulta em uma solicitação que solicita ao usuário via interface do usuário.
  • O MSAL suporta o início de sessão a partir de um browser predefinido ou de uma vista Web incorporada:
    • Por padrão, o navegador padrão no dispositivo é usado. Isso permite que a MSAL use o estado de autenticação (cookies) que já pode estar presente para uma ou mais contas conectadas. Se nenhum estado de autenticação estiver presente, a autenticação durante a autorização via MSAL resultará na criação do estado de autenticação (cookies) para o benefício de outros aplicativos da Web que serão usados no mesmo navegador.
  • Novo modelo de exceção:
    • As exceções definem mais claramente o tipo de erro que ocorreu e o que o desenvolvedor precisa fazer para resolvê-lo.
  • MSAL suporta objetos de parâmetro para AcquireToken e AcquireTokenSilent chamadas.
  • O MSAL suporta configuração declarativa para:
    • ID do cliente, URI de redirecionamento.
    • Navegador incorporado vs padrão
    • Autoridades
    • Configurações HTTP, como leitura e tempo limite de conexão

Seu registro de aplicativo e migração para MSAL

Não é necessário alterar o registo da aplicação existente para utilizar o MSAL. Se quiser aproveitar o consentimento incremental/progressivo, talvez seja necessário revisar o registro para identificar os escopos específicos que deseja solicitar incrementalmente. Seguem-se mais informações sobre âmbitos e consentimento incremental.

No registro do aplicativo no portal, você verá uma guia de permissões da API. Isso fornece uma lista das APIs e permissões (escopos) para as quais seu aplicativo está configurado atualmente para solicitar acesso. Ele também mostra uma lista dos nomes de escopo associados a cada permissão de API.

Com a ADAL e o ponto de extremidade do Azure AD v1.0, o consentimento do usuário para os recursos que possui foi concedido na primeira utilização. Com a MSAL e a plataforma de identidade da Microsoft, o consentimento pode ser solicitado de forma incremental. O consentimento incremental é útil para permissões que um usuário pode considerar alto privilégio ou pode questionar se não for fornecida uma explicação clara do motivo pelo qual a permissão é necessária. Na ADAL, essas permissões podem ter resultado no abandono de entrada do usuário no seu aplicativo.

Gorjeta

Use o consentimento incremental para fornecer contexto adicional aos usuários sobre por que seu aplicativo precisa de uma permissão.

Os administradores da organização podem consentir com as permissões que seu aplicativo requer em nome de todos os membros de sua organização. Algumas organizações só permitem que os administradores autorizem os aplicativos. O consentimento do administrador requer que você inclua todas as permissões e escopos de API usados pelo seu aplicativo no registro do aplicativo.

Gorjeta

Embora você possa solicitar um escopo usando o MSAL para algo não incluído no registro do seu aplicativo, recomendamos que você atualize o registro do aplicativo para incluir todos os recursos e escopos aos quais um usuário poderia conceder permissão.

Migrando de IDs de recursos para escopos

Autenticar e solicitar autorização para todas as permissões no primeiro uso

Se você estiver usando a ADAL e não precisar usar o consentimento incremental, a maneira mais simples de começar a usar a MSAL é fazer uma acquireToken solicitação usando o novo AcquireTokenParameter objeto e definindo o valor da ID do recurso.

Atenção

Não é possível definir escopos e uma ID de recurso. A tentativa de definir ambos resultará em um IllegalArgumentExceptionarquivo .

Isso resultará no mesmo comportamento v1 que você está usando. Todas as permissões solicitadas no registro do aplicativo são solicitadas ao usuário durante a primeira interação.

Autenticar e solicitar permissões somente conforme necessário

Para aproveitar o consentimento incremental, faça uma lista de permissões (escopos) que seu aplicativo usa do registro do aplicativo e organize-as em duas listas com base em:

  • Quais escopos você deseja solicitar durante a primeira interação do usuário com seu aplicativo durante o login.
  • As permissões associadas a um recurso importante do seu aplicativo que você também precisará explicar ao usuário.

Depois de organizar os escopos, organize cada lista para qual recurso (API) você deseja solicitar um token. Assim como quaisquer outros escopos que você deseja que o usuário autorize ao mesmo tempo.

O objeto de parâmetros usado para fazer sua solicitação à MSAL suporta:

  • Scope: A lista de escopos para os quais você deseja solicitar autorização e receber um token de acesso.
  • ExtraScopesToConsent: Uma lista adicional de escopos para os quais você deseja solicitar autorização enquanto solicita um token de acesso para outro recurso. Essa lista de escopos permite minimizar o número de vezes que você precisa solicitar autorização do usuário. O que significa menos solicitações de autorização ou consentimento do usuário.

Migrar de AuthenticationContext para PublicClientApplications

Construindo PublicClientApplication

Quando você usa o MSAL, você instancia um PublicClientApplicationarquivo . Este objeto modela a identidade do seu aplicativo e é usado para fazer solicitações a uma ou mais autoridades. Com este objeto, você configurará a identidade do cliente, redirecionará o URI, a autoridade padrão, se deseja usar o navegador do dispositivo versus a exibição da Web incorporada, o nível de log e muito mais.

Você pode configurar declarativamente esse objeto com JSON, que você fornece como um arquivo ou armazena como um recurso em seu APK.

Embora esse objeto não seja um singleton, internamente ele usa compartilhado Executors para solicitações interativas e silenciosas.

Empresa a Empresa

Na ADAL, cada organização da qual você solicita tokens de acesso requer uma instância separada do AuthenticationContext. Na MSAL, isso não é mais um requisito. Você pode especificar a autoridade da qual deseja solicitar um token como parte de sua solicitação silenciosa ou interativa.

Migrar da validação de autoridade para autoridades conhecidas

O MSAL não tem um sinalizador para habilitar ou desabilitar a validação de autoridade. A validação de autoridade é um recurso na ADAL e nas primeiras versões do MSAL que impede que seu código solicite tokens de uma autoridade potencialmente mal-intencionada. O MSAL agora recupera uma lista de autoridades conhecidas pela Microsoft e mescla essa lista com as autoridades que você especificou em sua configuração.

Gorjeta

Se você for um usuário B2C (Business to Consumer) do Azure, isso significa que não precisa mais desabilitar a validação de autoridade. Em vez disso, inclua cada uma das suas políticas do Azure AD B2C suportadas como autoridades na sua configuração MSAL.

Se você tentar usar uma autoridade que não é conhecida pela Microsoft e não está incluída em sua configuração, você receberá um UnknownAuthorityExceptionarquivo .

Registo

Agora você pode configurar declarativamente o log como parte de sua configuração, desta forma:

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

Migrar de UserInfo para Conta

Na ADAL, o AuthenticationResult fornece um UserInfo objeto usado para recuperar informações sobre a conta autenticada. O termo "usuário", que significava um agente humano ou de software, foi aplicado de uma forma que dificultou a comunicação de que alguns aplicativos suportam um único usuário (seja um agente humano ou de software) que tem várias contas.

Considere uma conta bancária. Você pode ter mais de uma conta em mais de uma instituição financeira. Quando você abre uma conta, você (o usuário) recebe credenciais, como um Cartão Multibanco ou PIN, que são usadas para acessar seu saldo, pagamentos de contas e assim por diante, para cada conta. Essas credenciais só podem ser utilizadas na instituição financeira que as emitiu.

Por analogia, como as contas em uma instituição financeira, as contas na plataforma de identidade da Microsoft são acessadas usando credenciais. Essas credenciais são registradas ou emitidas pela Microsoft. Ou pela Microsoft em nome de uma organização.

Onde a plataforma de identidade da Microsoft difere de uma instituição financeira, nesta analogia, é que a plataforma de identidade da Microsoft fornece uma estrutura que permite que um usuário use uma conta e suas credenciais associadas para acessar recursos que pertencem a vários indivíduos e organizações. É como poder usar um cartão emitido por um banco, em mais uma instituição financeira. Isso funciona porque todas as organizações em questão estão usando a plataforma de identidade da Microsoft, que permite que uma conta seja usada em várias organizações. Eis um exemplo:

Sam trabalha para Contoso.com mas gerencia máquinas virtuais do Azure que pertencem a Fabrikam.com. Para Sam gerenciar as máquinas virtuais da Fabrikam, ele precisa estar autorizado a acessá-las. Esse acesso pode ser concedido adicionando a conta de Sam ao Fabrikam.com e concedendo a sua conta uma função que lhe permite trabalhar com as máquinas virtuais. Isso seria feito com o portal do Azure.

Adicionar a conta Contoso.com de Sam como membro do Fabrikam.com resultaria na criação de um novo registro no Microsoft Entra ID de Fabrikam.com para Sam. O registro de Sam no Microsoft Entra ID é conhecido como um objeto de usuário. Nesse caso, esse objeto de usuário apontaria de volta para o objeto de usuário de Sam em Contoso.com. O objeto de usuário Fabrikam de Sam é a representação local de Sam e seria usado para armazenar informações sobre a conta associada a Sam no contexto de Fabrikam.com. Em Contoso.com, o título de Sam é Senior DevOps Consultant. Na Fabrikam, o título de Sam é Contractor-Virtual Machines. Além Contoso.com, Sam não é responsável, nem autorizado, a gerenciar máquinas virtuais. Na Fabrikam.com, essa é a sua única função. No entanto, Sam ainda só tem um conjunto de credenciais para acompanhar, que são as credenciais emitidas por Contoso.com.

Quando uma chamada bem-sucedida acquireToken for feita, você verá uma referência a um IAccount objeto que pode ser usado em solicitações posteriores acquireTokenSilent .

IMultiTenantAccount

Se você tiver um aplicativo que acessa declarações sobre uma conta de cada um dos locatários nos quais a conta está representada, poderá converter IAccount objetos para IMultiTenantAccount. Essa interface fornece um mapa de , digitado por ID de ITenantProfileslocatário, que permite acessar as declarações que pertencem à conta em cada um dos locatários aos quais você solicitou um token, em relação à conta atual.

As reivindicações na raiz do IAccount e IMultiTenantAccount sempre contêm as reivindicações do inquilino da casa. Se você ainda não fez uma solicitação de um token dentro do inquilino da casa, essa coleção estará vazia.

Outras alterações

Use o novo 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);
}

Migrar para as novas exceções

Na ADAL, há um tipo de exceção, AuthenticationExceptionque inclui um método para recuperar o valor do ADALError enum. No MSAL, há uma hierarquia de exceções e cada uma tem seu próprio conjunto de códigos de erro específicos associados.

Exceção Description
MsalArgumentException Lançado se um ou mais argumentos de entrada forem inválidos.
MsalClientException Lançado se o erro for do lado do cliente.
MsalDeclinedScopeException Lançado se um ou mais escopos solicitados forem recusados pelo servidor.
MsalException Exceção verificada padrão lançada pelo MSAL.
MsalIntuneAppProtectionPolicyRequiredException Lançado se o recurso tiver a política de proteção MAMCA habilitada.
MsalServiceException Lançado se o erro for do lado do servidor.
MsalUiRequiredException Lançado se o token não puder ser atualizado silenciosamente.
MsalUserCancelException Lançado se o usuário cancelou o fluxo de autenticação.

Tradução de ADALError para MsalException

Se você está pegando esses erros na ADAL... ... detetar estas exceções MSAL:
Sem ADALError equivalente 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
Sem ADALError equivalente MsalDeclinedScopeException
  • ADALError.APP_PACKAGE_NAME_NOT_FOUND
  • ADALError.BROKER_APP_VERIFICATION_FAILED
  • ADALError.PACKAGE_NAME_NOT_FOUND
MsalException
Sem ADALError equivalente MsalIntuneAppProtectionPolicyRequiredException
  • ADALError.SERVER_ERROR
  • ADALError.SERVER_INVALID_REQUEST
MsalServiceException
  • ADALError.AUTH_REFRESH_FAILED_PROMPT_NOT_ALLOWED
MsalUiRequiredException
Sem ADALError equivalente MsalUserCancelException

Registo ADAL para registo 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
}