Поделиться через


Требования к конфигурации и советы по устранению неполадок для Xamarin Android с MSAL.NET

Существует несколько изменений конфигурации, которые необходимо внести в код при использовании Xamarin Android с библиотекой проверки подлинности Майкрософт для .NET (MSAL.NET). Необходимые изменения описываются в следующих разделах, а за ними следует раздел Устранение неполадок, который поможет избежать некоторых наиболее распространенных проблем.

Примечание.

MSAL.NET версии 4.61.0 и выше не поддерживают универсальная платформа Windows (UWP), Xamarin Android и Xamarin iOS. Мы рекомендуем перенести приложения Xamarin в современные платформы, такие как MAUI. Дополнительные сведения о нерекомендуемом объявлении о предстоящей отмене MSAL.NET для Xamarin и UWP.

Установка родительского действия

Установите родительское действие в Xamarin Android, чтобы токен возвращался после взаимодействия:

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

В MSAL.NET 4.2 и более поздних версий можно также задать эту функцию на уровне [PublicClientApplication][PublicClientApplication]. Для этого используйте обратный вызов:

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

Если вы используете CurrentActivityPlugin, то код построителя [PublicClientApplication][PublicClientApplication] должен выглядеть примерно так, как в этом фрагменте кода:

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

Обеспечение возврата элемента управления в MSAL.

Когда интерактивная часть потока проверки подлинности заканчивается, верните управление в MSAL, переопределив [][Activityдействие].[OnActivityResult()] Метод [OnActivityResult].

В переопределении вызовите MSAL. AuthenticationContinuationHelperNET.SetAuthenticationContinuationEventArgs() для возврата элемента управления в MSAL в конце интерактивной части потока проверки подлинности.

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

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

Обновление манифеста Android для поддержки System WebView

Для поддержки System WebView файл AndroidManifest.xml должен содержать следующие значения:

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

Значение android:scheme создается из URI перенаправления, настроенного на портале приложения. Например, если URI перенаправления — msal00001111-aaaa-2222-bbbb-3333cccc4444://auth, то запись android:scheme в манифесте будет выглядеть, как в следующем примере:

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

Кроме того, можно создать действие в коде, а не вручную изменять AndroidManifest.xml. Чтобы создать действие в коде, сначала создайте класс, включающий атрибут Activity и атрибут IntentFilter.

Ниже приведен пример класса, представляющего значения XML-файла:

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

Использование System WebView при проверке подлинности через брокера

Чтобы использовать System WebView в качестве резервного варианта для интерактивной проверки подлинности, если вы настроили свое приложение для использования брокера при проверке подлинности, и на устройстве не установлен брокер, включите MSAL для получения ответа проверки подлинности с помощью URI перенаправления брокера. MSAL попытается выполнить проверку подлинности с помощью System WebView на устройстве по умолчанию, когда обнаружит, что брокер недоступен. Использование по умолчанию этого метода приведет к сбою, так как URI перенаправления настроен для использования брокера, а System WebView не знает, как использовать его для возврата в MSAL. Чтобы устранить эту проблему, создайте фильтр намерений с помощью URI перенаправления брокера, настроенного ранее. Добавьте фильтр намерений, изменив манифест приложения, как показано в следующем примере:

<!--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>

Замените имя пакета, зарегистрированного на портале Azure, значением android:host=. Замените хэш ключа, зарегистрированного на портале Azure, значением android:path=. Недопустимо применять к хэшу подписи кодирование по правилам для URL-адреса. Убедитесь, что в начале хэша подписи присутствует косая черта (/).

Манифест Xamarin.Forms 4.3.x

Xamarin.Forms 4.3.x создает код, который присваивает атрибут package для com.companyname.{appName} в AndroidManifest.xml. При использовании DataScheme как msal{client_id} может потребоваться изменить значение, чтобы оно совпадало со значением пространства имен MainActivity.cs.

Поддержка Android 11

Чтобы использовать системный браузер и проверку подлинности через брокера в Android 11, необходимо сначала объявить эти пакеты, чтобы они были видны приложению. Приложения, предназначенные для Android 10 (API 29) и более ранних версий, могут запрашивать у операционной системы список пакетов, доступных на устройстве в любое время. Для обеспечения конфиденциальности и безопасности Android 11 сокращает количество видимых пакетов до списка пакетов ОС по умолчанию и пакетов, указанных в файле AndroidManifest.xml приложения.

Чтобы разрешить приложению выполнять проверку подлинности с помощью как системного браузера, так и брокера, добавьте следующий раздел в 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>

Замените {Package Name} именем пакета приложения.

Обновленный манифест, который включает поддержку проверки подлинности с помощью системного браузера и брокера, должен выглядеть, как в следующем примере:

<?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>

Использование внедренного веб-представления (необязательно)

По умолчанию MSAL.NET использует системный веб-браузер. Этот браузер позволяет использовать единый вход (SSO) с помощью веб-приложений и других приложений. В некоторых редких случаях может потребоваться, чтобы система использовала встроенное веб-представление.

В этом примере кода показано, как настроить встроенное веб-представление:

bool useEmbeddedWebView = !app.IsSystemWebViewAvailable;

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

Дополнительные сведения см. в статье Использование веб-браузеров для MSAL.NET и Рекомендации по системному браузеру Xamarin Android.

Устранение неполадок

Общие советы

  • Обновите существующий пакет NuGet MSAL.NET до последней версии MSAL.NET.
  • Убедитесь, что используется Xamarin.Forms последней версии.
  • Убедитесь, что используется Xamarin.Android.Support.v4 последней версии.
  • Убедитесь, что все пакеты Xamarin.Android.Support предназначены для последней версии.
  • Очистите или перестройте приложение.
  • В Visual Studio попробуйте изменить максимальное количество параллельных сборок проекта на 1. Для этого выберите Параметры>Проекты и решения>Создание и запуск>Максимальное количество параллельных сборок проектов.
  • При сборке из командной строки и использовании вашей командой элемента /m попробуйте удалить его из команды.

Ошибка: имя AuthenticationContinuationHelper не существует в текущем контексте

Если ошибка сообщает, что AuthenticationContinuationHelper не существует в текущем контексте, то, возможно, Visual Studio был неправильно обновлен файл Android.csproj*. Иногда путь к файлу в элементе <HintPath> ошибочно содержит netstandard13 вместо monoandroid90.

В следующем примере приведен правильный путь к файлу:

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

Следующие шаги

Чтобы попробовать другие примеры, перейдите к разделу Мобильные общедоступные клиентские приложения.