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.