Partilhar via


Requisitos de configuração e dicas de solução de problemas para o Xamarin Android com MSAL.NET

Há várias alterações de configuração que você precisa fazer em seu código ao usar o Xamarin Android com a Biblioteca de Autenticação da Microsoft para .NET (MSAL.NET). As seções a seguir descrevem as modificações necessárias, seguidas por uma seção Solução de problemas para ajudá-lo a evitar alguns dos problemas mais comuns.

Nota

MSAL.NET versões 4.61.0 e superiores não oferecem suporte para a Plataforma Universal do Windows (UWP), Xamarin Android e Xamarin iOS. Recomendamos que você migre seus aplicativos Xamarin para estruturas modernas como MAUI. Leia mais sobre a descontinuação em Anunciando a próxima substituição do MSAL.NET para Xamarin e UWP.

Definir a atividade pai

No Xamarin Android, defina a atividade pai para que o token retorne após a interação:

var authResult = AcquireTokenInteractive(scopes)
 .WithParentActivityOrWindow(parentActivity)
 .ExecuteAsync();

No MSAL.NET 4.2 e posterior, você também pode definir essa funcionalidade no nível de [PublicClientApplication][PublicClientApplication]. Para fazer isso, use um retorno de chamada:

// Requires MSAL.NET 4.2 or later
var pca = PublicClientApplicationBuilder
  .Create("<your-client-id-here>")
  .WithParentActivityOrWindow(() => parentActivity)
  .Build();

Se você usar CurrentActivityPlugin, seu código do construtor [PublicClientApplication][PublicClientApplication] deverá ser semelhante a este trecho de código:

// Requires MSAL.NET 4.2 or later
var pca = PublicClientApplicationBuilder
  .Create("<your-client-id-here>")
  .WithParentActivityOrWindow(() => CrossCurrentActivity.Current)
  .Build();

Garantir que o controle retorne ao MSAL

Quando a parte interativa do fluxo de autenticação terminar, retorne o controle ao MSAL substituindo [Activity][Activity].[OnActivityResult()]Método [OnActivityResult].

Na sua substituição, chame MSAL. NET's AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs() método para retornar o controle para MSAL no final da parte interativa do fluxo de autenticação.

protected override void OnActivityResult(int requestCode,
                                         Result resultCode,
                                         Intent data)
{
    base.OnActivityResult(requestCode, resultCode, data);

    // Return control to MSAL
    AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(requestCode,
                                                                            resultCode,
                                                                            data);
}

Atualizar o manifesto do Android para suporte ao System WebView

Para suportar o System WebView, o ficheiro AndroidManifest.xml deve conter os seguintes valores:

<activity android:name="microsoft.identity.client.BrowserTabActivity" android:configChanges="orientation|screenSize" android:exported="true">
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="msal{Client Id}" android:host="auth" />
  </intent-filter>
</activity>

O android:scheme valor é criado a partir do URI de redirecionamento configurado no portal do aplicativo. Por exemplo, se o URI de redirecionamento for msal00001111-aaaa-2222-bbbb-3333cccc4444://auth, a android:scheme entrada no manifesto será semelhante a este exemplo:

<data android:scheme="msal00001111-aaaa-2222-bbbb-3333cccc4444" android:host="auth" />

Como alternativa, crie a atividade no código em vez de editá AndroidManifest.xml manualmente. Para criar a atividade no código, primeiro crie uma classe que inclua o Activity atributo e o IntentFilter atributo.

Aqui está um exemplo de uma classe que representa os valores do arquivo XML:

  [Activity(Exported = true)]
  [IntentFilter(new[] { Intent.ActionView },
        Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault },
        DataHost = "auth",
        DataScheme = "msal{client_id}")]
  public class MsalActivity : BrowserTabActivity
  {
  }

Usar o System WebView na autenticação intermediada

Para usar o System WebView como um fallback para autenticação interativa quando você configurou seu aplicativo para usar a autenticação intermediada e o dispositivo não tem um broker instalado, habilite o MSAL para capturar a resposta de autenticação usando o URI de redirecionamento do broker. O MSAL tentará autenticar usando o WebView do sistema padrão no dispositivo quando detetar que o broker não está disponível. Usando esse padrão, ele falhará porque o URI de redirecionamento está configurado para usar um broker e o System WebView não sabe como usá-lo para retornar ao MSAL. Para resolver isso, crie um filtro de intenção usando o URI de redirecionamento do broker que você configurou anteriormente. Adicione o filtro de intenção modificando o manifesto do seu aplicativo como este exemplo:

<!--Intent filter to capture System WebView or Authenticator calling back to our app after sign-in-->
<activity
      android:name="microsoft.identity.client.BrowserTabActivity">
    <intent-filter>
          <action android:name="android.intent.action.VIEW" />
          <category android:name="android.intent.category.DEFAULT" />
          <category android:name="android.intent.category.BROWSABLE" />
          <data android:scheme="msauth"
              android:host="Enter_the_Package_Name"
              android:path="/Enter_the_Signature_Hash" />
    </intent-filter>
</activity>

Substitua o nome do pacote que você registrou no portal do Azure para o android:host= valor. Substitua o hash da chave que registou no portal do Azure para o valor android:path=. O hash de assinatura não deve ser codificado por URL. Verifique se aparece uma barra / no início do hash de assinatura.

Manifesto do Xamarin.Forms 4.3.x

Xamarin.Forms 4.3.x gera código que define o package atributo para com.companyname.{appName} em AndroidManifest.xml. Se você usar DataScheme como msal{client_id}, talvez queira alterar o valor para corresponder ao valor do MainActivity.cs namespace.

Suporte para Android 11

Para usar o navegador do sistema e a autenticação intermediada no Android 11, você deve primeiro declarar esses pacotes, para que fiquem visíveis para o aplicativo. Os aplicativos destinados ao Android 10 (API 29) e anteriores podem consultar o sistema operacional para obter uma lista de pacotes disponíveis no dispositivo a qualquer momento. Para oferecer suporte à privacidade e segurança, o Android 11 reduz a visibilidade do pacote para uma lista padrão de pacotes do sistema operacional e os pacotes especificados no arquivo AndroidManifest.xml do aplicativo.

Para permitir que o aplicativo se autentique usando o navegador do sistema e o broker, adicione a seguinte seção ao AndroidManifest.xml:

<!-- Required for API Level 30 to make sure the app can detect browsers and other apps where communication is needed.-->
<!--https://developer.android.com/training/basics/intents/package-visibility-use-cases-->
<queries>
  <package android:name="com.azure.authenticator" />
  <package android:name="{Package Name}" />
  <package android:name="com.microsoft.windowsintune.companyportal" />
  <!-- Required for API Level 30 to make sure the app detect browsers
      (that don't support custom tabs) -->
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" />
  </intent>
  <!-- Required for API Level 30 to make sure the app can detect browsers that support custom tabs -->
  <!-- https://developers.google.com/web/updates/2020/07/custom-tabs-android-11#detecting_browsers_that_support_custom_tabs -->
  <intent>
    <action android:name="android.support.customtabs.action.CustomTabsService" />
  </intent>
</queries>

Substitua {Package Name} pelo nome do pacote do aplicativo.

Seu manifesto atualizado, que agora inclui suporte para o navegador do sistema e autenticação intermediada, deve ser semelhante a este exemplo:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.XamarinDev">
    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <application android:theme="@android:style/Theme.NoTitleBar">
        <activity android:name="microsoft.identity.client.BrowserTabActivity" android:configChanges="orientation|screenSize">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="msal00001111-aaaa-2222-bbbb-3333cccc4444" android:host="auth" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="msauth" android:host="com.companyname.XamarinDev" android:path="/Fc4l/5I4mMvLnF+l+XopDuQ2gEM=" />
            </intent-filter>
        </activity>
    </application>
    <!-- Required for API Level 30 to make sure we can detect browsers and other apps we want to
     be able to talk to.-->
    <!--https://developer.android.com/training/basics/intents/package-visibility-use-cases-->
    <queries>
        <package android:name="com.azure.authenticator" />
        <package android:name="com.companyname.xamarindev" />
        <package android:name="com.microsoft.windowsintune.companyportal" />
        <!-- Required for API Level 30 to make sure we can detect browsers
        (that don't support custom tabs) -->
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
        </intent>
        <!-- Required for API Level 30 to make sure we can detect browsers that support custom tabs -->
        <!-- https://developers.google.com/web/updates/2020/07/custom-tabs-android-11#detecting_browsers_that_support_custom_tabs -->
        <intent>
            <action android:name="android.support.customtabs.action.CustomTabsService" />
        </intent>
    </queries>
</manifest>

Utilizar a vista Web incorporada (opcional)

Por padrão, MSAL.NET usa o navegador da Web do sistema. Este navegador permite-lhe obter início de sessão único (SSO) utilizando aplicações Web e outras aplicações. Em alguns casos raros, você pode querer que seu sistema use uma exibição da Web incorporada.

Este exemplo de código mostra como configurar uma exibição da Web incorporada:

bool useEmbeddedWebView = !app.IsSystemWebViewAvailable;

var authResult = AcquireTokenInteractive(scopes)
 .WithParentActivityOrWindow(parentActivity)
 .WithEmbeddedWebView(useEmbeddedWebView)
 .ExecuteAsync();

Para obter mais informações, consulte Usar navegadores da Web para considerações sobre o navegador do sistema MSAL.NET e Xamarin Android.

Resolução de Problemas

Sugestões gerais

  • Atualize o pacote NuGet do MSAL.NET existente para a versão mais recente do MSAL.NET.
  • Verifique se o Xamarin.Forms está na versão mais recente.
  • Verifique se o Xamarin.Android.Support.v4 está na versão mais recente.
  • Certifique-se de que todos os pacotes Xamarin.Android.Support tenham como destino a versão mais recente.
  • Limpe ou reconstrua o aplicativo.
  • No Visual Studio, tente definir o número máximo de compilações de projeto paralelo como 1. Para fazer isso, selecione Opções>Projetos e Soluções>Criar e Executar>Número máximo de compilações de projetos paralelos.
  • Se você estiver criando a partir da linha de comando e seu comando usar /m, tente remover esse elemento do comando.

Erro: O nome AuthenticationContinuationHelper não existe no contexto atual

Se um erro indicar que AuthenticationContinuationHelper não existe no contexto atual, o Visual Studio pode ter atualizado incorretamente o arquivo Android.csproj* . Às vezes, o caminho do <HintPath> arquivo no elemento contém netstandard13 incorretamente em vez de monoandroid90.

Este exemplo contém um caminho de arquivo correto:

<Reference Include="Microsoft.Identity.Client, Version=3.0.4.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae,
           processorArchitecture=MSIL">
  <HintPath>..\..\packages\Microsoft.Identity.Client.3.0.4-preview\lib\monoandroid90\Microsoft.Identity.Client.dll</HintPath>
</Reference>

Próximos passos

Para experimentar exemplos adicionais, aplicativos cliente públicos móveis.