使用 MSAL.NET 的 Xamarin Android 設定需求和疑難解答秘訣

使用 Xamarin Android 搭配適用於 .NET 的 Microsoft 驗證連結庫時,您需要進行數個設定變更(MSAL.NET)。 下列各節描述必要的修改,後面接著疑難解答節,以協助您避免一些最常見的問題。

設定父活動

在 Xamarin Android 上,設定父活動,讓令牌在互動之後傳回:

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

在 MSAL.NET 4.2 和更新版本中,您也可以在 PublicClientApplication 層級設定此功能。 若要這樣做,請使用回呼:

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

如果您使用 CurrentActivityPlugin,則您的產生器程式 PublicClientApplication 代碼看起來應該類似下列代碼段:

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

確定控件會返回 MSAL

當驗證流程的互動式部分結束時,藉由覆寫 Activity,將控制權傳回 MSAL。OnActivityResult() 方法。

在您的覆寫中,呼叫 MSAL。NET 的 AuthenticationContinuationHelperSetAuthenticationContinuationEventArgs() 方法,在驗證流程的互動式部分結尾,將控制權傳回 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);
}

更新 System WebView 支援的 Android 指令清單

若要支援 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://authandroid: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 作為互動式驗證的後援,請使用訊息代理程式的重新導向 URI 啟用 MSAL 來擷取驗證回應。 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 會將套件可見度減少為預設的 OS 套件清單,以及應用程式 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 會使用系統網頁瀏覽器。 此瀏覽器可讓您使用 Web 應用程式和其他應用程式來取得單一登入 (SSO)。 在某些情況下,您可能想要讓系統使用內嵌 Web 檢視。

此程式代碼範例示範如何設定內嵌 Web 檢視:

bool useEmbeddedWebView = !app.IsSystemWebViewAvailable;

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

如需詳細資訊,請參閱 使用網頁瀏覽器進行 MSAL.NETXamarin Android 系統瀏覽器考慮

疑難排解

一般提示

  • 將現有的 MSAL.NET NuGet 套件更新為 最新版本的 MSAL.NET
  • 確認 Xamarin.Forms 處於最新版本。
  • 確認 Xamarin.Android.Support.v4 是最新版本。
  • 確定所有 Xamarin.Android.Support 套件都以最新版本為目標。
  • 清除或重建應用程式。
  • 在Visual Studio中,嘗試將平行專案組建數目上限設定為 1。 若要這樣做,請選取 [選項>專案和方案>建置] 和 [執行>平行專案組建數目上限]。
  • 如果您要從命令行建置,而且您的命令使用 /m,請嘗試從 命令中移除這個專案。

錯誤:目前內容中不存在 AuthenticationContinuationHelper 名稱

如果錯誤指出 AuthenticationContinuationHelper 目前內容中不存在,Visual Studio 可能會錯誤地更新 Android.csproj* 檔案。 有時候元素中的 <HintPath> 檔案路徑不正確包含 netstandard13monoandroid90而不是 。

這個範例包含正確的檔案路徑:

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

下一步

如需詳細資訊,請參閱使用 Microsoft 身分識別平台Xamarin 行動應用程式範例。 下表摘要說明自述檔案中的相關信息。

範例 平台 描述
https://github.com/Azure-Samples/active-directory-xamarin-native-v2 Xamarin.iOS、Android、UWP Xamarin 行動應用程式,示範如何使用 MSAL.NET,使用 Microsoft 身分識別平台 驗證公司或學校和 Microsoft 個人帳戶,並使用產生的令牌存取 Microsoft Graph API。
驗證流程圖表