在 Xamarin 應用程式中使用 Microsoft Authenticator 或 Intune 公司入口網站

在 Android 和 iOS 上,Microsoft Authenticator 和 Android 特定 Microsoft Intune 公司入口網站等訊息代理程式會啟用:

  • 單一登入 (SSO) :使用者不需要登入每個應用程式。
  • 裝置識別 :訊息代理程式會存取裝置憑證。 當裝置加入工作場所時,會在裝置上建立此憑證。
  • 應用程式識別驗證 :當應用程式呼叫訊息代理程式時,它會傳遞其重新導向 URL。 訊息代理程式會驗證 URL。

若要啟用其中一項功能,請在呼叫 PublicClientApplicationBuilder.CreateApplication 方法時使用 WithBroker() 參數。 .WithBroker()參數預設會設定為 true。

在適用于 .NET 的 Microsoft 驗證程式庫中設定代理驗證(MSAL.NET)會因平臺而異:

iOS 的代理驗證

使用下列步驟,讓您的 Xamarin.iOS 應用程式能夠與 Microsoft Authenticator 應用程式通訊。 如果您的目標是 iOS 13,請考慮閱讀 Apple 的重大 API 變更

步驟 1:啟用訊息代理程式支援

您必須為 的個別實例 PublicClientApplication 啟用訊息代理程式支援。 預設會停用支援。 當您透過 PublicClientApplicationBuilder 建立 PublicClientApplication 時,請使用 WithBroker() 參數,如下列範例所示。 WithBroker()參數預設會設定為 true。

var app = PublicClientApplicationBuilder
                .Create(ClientId)
                .WithBroker()
                .WithReplyUri(redirectUriOnIos) // $"msauth.{Bundle.Id}://auth" (see step 6 below)
                .Build();

步驟 2:啟用金鑰鏈存取

若要啟用金鑰鏈存取,您必須擁有應用程式的金鑰鏈存取群組。 當您建立應用程式時, WithIosKeychainSecurityGroup() 您可以使用 API 來設定金鑰鏈存取群組:

var builder = PublicClientApplicationBuilder
     .Create(ClientId)
     .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
     .Build();

如需詳細資訊,請參閱 啟用金鑰鏈存取

步驟 3:更新 AppDelegate 以處理回呼

MSAL.NET 呼叫訊息代理程式時,訊息代理程式會透過 OpenUrl 類別的 AppDelegate 方法回呼您的應用程式。 因為 MSAL 會等候訊息代理程式回應,因此您的應用程式必須配合以呼叫 MSAL.NET 回來。 若要啟用這項合作,請更新 AppDelegate.cs 檔案以覆寫下列方法。

public override bool OpenUrl(UIApplication app, NSUrl url,
                             string sourceApplication,
                             NSObject annotation)
{
    if (AuthenticationContinuationHelper.IsBrokerResponse(sourceApplication))
    {
      AuthenticationContinuationHelper.SetBrokerContinuationEventArgs(url);
      return true;
    }

    else if (!AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url))
    {
         return false;
    }

    return true;
}

每次啟動應用程式時,都會叫用這個方法。 它可用來處理來自訊息代理程式的回應,並完成 MSAL.NET 啟動的驗證程式。

步驟 4:設定 UIViewController()

仍在 AppDelegate.cs 檔案中 ,設定物件視窗。 您通常不需要設定 Xamarin iOS 的物件視窗,但您需要物件視窗來傳送和接收來自訊息代理程式的回應。

若要設定物件視窗:

  1. 在 AppDelegate.cs 檔案中 ,將 設定 App.RootViewController 為新的 UIViewController() 此指派可確保對 Broker 的呼叫包含 UIViewController 。 如果未正確指派此設定,您可能會收到此錯誤:

    "uiviewcontroller_required_for_ios_broker":"UIViewController is null, so MSAL.NET cannot invoke the iOS broker. See https://aka.ms/msal-net-ios-broker"

  2. 在呼叫時 AcquireTokenInteractive ,使用 .WithParentActivityOrWindow(App.RootViewController) ,然後將參考傳入您將使用的物件視窗。

    在 App.cs

       public static object RootViewController { get; set; }
    

    AppDelegate.cs 中:

       LoadApplication(new App());
       App.RootViewController = new UIViewController();
    

    在呼叫中 AcquireToken

    result = await app.AcquireTokenInteractive(scopes)
                 .WithParentActivityOrWindow(App.RootViewController)
                 .ExecuteAsync();
    

步驟 5:註冊 URL 配置

MSAL.NET 使用 URL 來叫用訊息代理程式,然後將訊息代理程式回應傳回至您的應用程式。 若要完成來回行程,請在 Info.plist 檔案中 註冊應用程式的 URL 配置。

名稱 CFBundleURLSchemes 必須包含 msauth. 為前置詞。 請遵循前置詞與 CFBundleURLName

在 URL 配置中, BundleId 可唯一識別應用程式: $"msauth.(BundleId)" 。 因此,如果 BundleIdcom.yourcompany.xforms ,則 URL 配置為 msauth.com.yourcompany.xforms

注意

此 URL 配置會成為從訊息代理程式收到回應時唯一識別您應用程式的重新導向 URI 的一部分。

 <key>CFBundleURLTypes</key>
    <array>
      <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>com.yourcompany.xforms</string>
        <key>CFBundleURLSchemes</key>
        <array>
          <string>msauth.com.yourcompany.xforms</string>
        </array>
      </dict>
    </array>

步驟 6:將訊息代理程式識別碼新增至 LSApplicationQueriesSchemes 區段

MSAL 會使用 –canOpenURL: 來檢查代理程式是否已安裝在裝置上。 在 iOS 9 中,Apple 鎖定了應用程式可以查詢的配置。

將 新增 msauthv2LSApplicationQueriesSchemes Info.plist 檔案的 區段,如下列範例所示:

<key>LSApplicationQueriesSchemes</key>
    <array>
      <string>msauthv2</string>
      <string>msauthv3</string>
    </array>

步驟 7:將重新導向 URI 新增至您的應用程式註冊

提示

本文中的步驟可能會根據您從開始的入口網站稍有不同。

當您使用訊息代理程式時,您的重新導向 URI 有額外的需求。 重新導向 URI 必須 具有下列格式:

$"msauth.{BundleId}://auth"

以下是範例:

public static string redirectUriOnIos = "msauth.com.yourcompany.XForms://auth";

請注意,重新導向 URI 符合 CFBundleURLSchemes 您在 Info.plist 檔案中包含的 名稱。

將重新導向 URI 新增至應用程式的註冊。 若要產生格式正確的重新導向 URI,請使用 應用程式註冊 從套件組合識別碼產生代理重新導向 URI。

若要產生重新導向 URI:

  1. 以至少雲端 應用程式管理員istrator 身分登入 Microsoft Entra 系統管理中心

  2. 流覽至 [ 身分 > 識別應用程式 > 應用程式註冊]。

  3. 搜尋並選取應用程式。

  4. 選取 [驗證 > ][新增平臺 > iOS/ macOS]

  5. 輸入您的套件組合識別碼,然後選取 [ 設定 ]。

    複製 [重新導向 URI] 文字方塊中出現的 產生的重新導向 URI ,以納入您的程式碼:

    iOS platform settings with generated redirect URI

  6. 選取 [完成 ] 以完成重新導向 URI 的產生。

Android 的代理驗證

步驟 1:啟用訊息代理程式支援

代理程式支援會依個別 PublicClientApplication 啟用。 此項目預設為停用。 透過 建立 IPublicClientApplicationPublicClientApplicationBuilder 時, WithBroker() 請使用 參數 (預設設定為 true)。

var app = PublicClientApplicationBuilder
                .Create(ClientId)
                .WithBroker()
                .WithRedirectUri(redirectUriOnAndroid) // See step #4
                .Build();

步驟 2:更新主要活動以處理回呼

當 MSAL.NET 呼叫訊息代理程式時,訊息代理程式會接著使用 OnActivityResult() 方法回呼您的應用程式。 由於 MSAL 會等候訊息代理程式回應,因此您的應用程式必須將結果路由傳送至 MSAL.NET。

覆寫 OnActivityResult() 方法,將結果路由至 SetAuthenticationContinuationEventArgs(int requestCode, Result resultCode, Intent data) 方法,如下所示:

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

每次啟動訊息代理程式應用程式時,都會叫用這個方法,並做為處理訊息代理程式回應的機會,並完成 MSAL.NET 啟動的驗證程式。

步驟 3:設定活動

若要啟用代理驗證,請設定活動,讓 MSAL 可以傳送和接收訊息代理程式的回應。 若要這樣做,請將活動 (通常是 MainActivity ) 提供給 WithParentActivityOrWindow(object parent) 父物件。

例如,在 對 的呼叫 AcquireTokenInteractive() 中:

result = await app.AcquireTokenInteractive(scopes)
             .WithParentActivityOrWindow((Activity)context))
             .ExecuteAsync();

步驟 4:將重新導向 URI 新增至您的應用程式註冊

MSAL 會使用 URL 叫用訊息代理程式,然後返回您的應用程式。 若要完成該來回行程,請註冊 應用程式的重新導向 URI

應用程式的重新導向 URI 格式取決於用來簽署 APK 的憑證。 例如:

msauth://com.microsoft.xforms.testApp/hgbUYHVBYUTvuvT&Y6tr554365466=

URI hgbUYHVBYUTvuvT&Y6tr554365466= 的最後一個部分是 APK 所簽署之簽章的 Base64 編碼版本。 在 Visual Studio 中開發您的應用程式時,如果您要偵錯程式碼而不使用特定憑證簽署 APK,Visual Studio 會簽署 APK 以供偵錯之用。 當 Visual Studio 以這種方式簽署 APK 時,它會為它所建置的電腦提供唯一的簽章。 因此,每次您在不同的電腦上建置應用程式時,都必須更新應用程式程式碼中的重新導向 URI 和應用程式的註冊,才能向 MSAL 進行驗證。

偵錯時,您可能會遇到 MSAL 例外狀況(或記錄訊息),指出提供的重新導向 URI 不正確。 例外狀況或記錄訊息也會指出您應該 用於偵錯目前電腦的重新導向 URI。 只要您在程式碼中更新重新導向 URI,並將提供的重新導向 URI 新增至應用程式的註冊,您就可以使用提供的重新導向 URI 繼續開發您的應用程式。

準備好完成程式碼之後,請更新程式碼中的重新導向 URI,以及應用程式的註冊,以使用您用來簽署 APK 的憑證簽章。

實際上,這表示您應該考慮為開發小組的每個成員新增重新導向 URI, 以及 生產簽署 APK 版本的重新導向 URI。

您可以自行計算簽章,類似于 MSAL 如何執行下列作業:

   private string GetRedirectUriForBroker()
   {
      string packageName = Application.Context.PackageName;
      string signatureDigest = this.GetCurrentSignatureForPackage(packageName);
      if (!string.IsNullOrEmpty(signatureDigest))
      {
            return string.Format(CultureInfo.InvariantCulture, "{0}://{1}/{2}", RedirectUriScheme,
               packageName.ToLowerInvariant(), signatureDigest);
      }

      return string.Empty;
   }

   private string GetCurrentSignatureForPackage(string packageName)
   {
      Android.Content.PM.Signature signature = null;
      if (Build.VERSION.SdkInt >= BuildVersionCodes.Tiramisu)
      {
          var packageInfo = Application.Context.PackageManager.GetPackageInfo(packageName, PackageManager.PackageInfoFlags.Of((long)PackageInfoFlags.SigningCertificates));
          if (packageInfo.SigningInfo != null)
          {
              var signatures = packageInfo.SigningInfo.GetApkContentsSigners();
              if (signatures != null && signatures.Length > 0)
                  signature = signatures[0];
          }
      }
      else
      {
#pragma warning disable CS0618 // Type or member is obsolete
          var packageInfo = Application.Context.PackageManager.GetPackageInfo(packageName, PackageInfoFlags.Signatures);
          if (packageInfo != null && packageInfo.Signatures != null && packageInfo.Signatures.Count > 0)
              signature = packageInfo.Signatures[0];
#pragma warning restore CS0618 // Type or member is obsolete
      }
    
      if (signature != null)
      {
          // First available signature. Applications can be signed with multiple signatures.
          // The order of Signatures is not guaranteed.
          var md = MessageDigest.GetInstance("SHA");
          md.Update(signature.ToByteArray());
          return Convert.ToBase64String(md.Digest(), Base64FormattingOptions.None);
          // Server side needs to register all other tags. ADAL will
          // send one of them.
      }
   }

您也可以選擇使用 keytool 搭配下列命令來取得套件的簽章:

  • Windows:
    keytool.exe -list -v -keystore "%LocalAppData%\Xamarin\Mono for Android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
    
  • macOS:
    keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
    

步驟 5 (選擇性):回復至系統瀏覽器

如果 MSAL 設定為使用訊息代理程式,但未安裝訊息代理程式,MSAL 會回到使用網頁檢視(瀏覽器)。 MSAL 會嘗試使用裝置上的預設系統瀏覽器進行驗證,因為已針對訊息代理程式設定重新導向 URI,而且系統瀏覽器不知道如何使用它來巡覽回 MSAL 而失敗。 若要避免失敗,您可以使用您在步驟 4 中使用的訊息代理程式重新導向 URI 來設定 意圖篩選

修改應用程式的資訊清單以新增意圖篩選:

<!-- NOTE the SLASH (required) that prefixes the signature value in the path attribute.
     The signature value is the Base64-encoded signature discussed above. -->
<intent-filter>
      <data android:scheme="msauth"
                    android:host="Package Name"
                    android:path="/Package Signature"/>

例如,如果您有 的 msauth://com.microsoft.xforms.testApp/hgbUYHVBYUTvuvT&Y6tr554365466= 重新導向 URI,您的資訊清單看起來應該像下列 XML 程式碼片段。

值中簽 android:path 章前面需要 正斜線 ( / )。

<!-- NOTE the SLASH (required) that prefixes the signature value in the path attribute.
     The signature value is the Base64-encoded signature discussed above. -->
<intent-filter>
      <data android:scheme="msauth"
                    android:host="com.microsoft.xforms.testApp"
                    android:path="/hgbUYHVBYUTvuvT&Y6tr554365466="/>

如需設定應用程式以取得系統瀏覽器和 Android 11 支援的詳細資訊,請參閱 更新系統瀏覽器支援的 Android 資訊清單。

或者,您可以將 MSAL 設定回內嵌瀏覽器,而內嵌瀏覽器不依賴重新導向 URI:

.WithUseEmbeddedWebUi(true)

Android 代理驗證的疑難排解秘訣

以下是在 Android 上實作代理驗證時避免問題的一些秘訣:

  • 重新導向 URI - 將重新導向 URI 新增至您的應用程式註冊。 遺失或不正確的重新導向 URI 是開發人員遇到的常見問題。

  • Broker 版本 - 安裝代理程式應用程式的最低必要版本。 這兩個應用程式之一可用於 Android 上的代理驗證。

  • Broker 優先順序 - MSAL 會在安裝 多個訊息代理程式時,與 安裝在裝置上的第一個訊息代理程式通訊。

    範例:如果您先安裝 Microsoft Authenticator,然後安裝Intune 公司入口網站,代理驗證只會 發生在 Microsoft Authenticator 上。

  • 記錄 - 如果您遇到代理驗證的問題,檢視訊息代理程式的記錄可能會協助您診斷原因。

    • 取得 Microsoft Authenticator 記錄:

      1. 選取應用程式右上角的功能表按鈕。
      2. 選取 [ 傳送有問題的意見 > 反應?]。
      3. 在 [您嘗試做什麼? ] 底下 ,選取選項並新增描述。
      4. 若要傳送記錄,請選取應用程式右上角的箭號。

      傳送記錄之後,對話方塊會顯示事件識別碼。 記錄事件識別碼,並在您要求協助時納入該識別碼。

    • 取得Intune 公司入口網站記錄:

      1. 選取應用程式左上角的功能表按鈕。
      2. 選取 [ 說明 > 電子郵件支援]。
      3. 若要傳送記錄,請選取 [ 上傳記錄]。

      傳送記錄之後,對話方塊會顯示事件識別碼。 記錄事件識別碼,並在您要求協助時納入該識別碼。

下一步

瞭解 搭配 MSAL.NET 使用 通用 Windows 平臺 的 考慮。