使用 Azure Active Directory B2C 驗證使用者

Azure Active Directory B2C 為面向消費者的 Web 和行動應用程式提供雲端身分識別管理。 本文說明如何使用 Azure Active Directory B2C,將身分識別管理整合到行動應用程式與 Microsoft 驗證連結庫。

概觀

Azure Active Directory B2C (ADB2C) 是取用者面向應用程式的身分識別管理服務。 它可讓使用者使用現有的社交帳戶或自定義認證登入您的應用程式,例如電子郵件或使用者名稱和密碼。 自訂認證帳戶稱為 本機 帳戶。

將 Azure Active Directory B2C 身分識別管理服務整合到行動應用程式中的程式如下:

  1. 建立 Azure Active Directory B2C 租用戶
  2. 向 Azure Active Directory B2C 租用戶註冊您的行動應用程式。
  3. 建立註冊和登入的原則,以及忘記密碼使用者流程。
  4. 使用 Microsoft 驗證連結庫 (MSAL) 來啟動 Azure Active Directory B2C 租使用者的驗證工作流程。

注意

如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶

Azure Active Directory B2C 支援多個識別提供者,包括 Microsoft、GitHub、Facebook、Twitter 等。 如需 Azure Active Directory B2C 功能的詳細資訊,請參閱 Azure Active Directory B2C 檔

Microsoft 驗證連結庫支援多個應用程式架構和平臺。 如需 MSAL 功能的相關信息,請參閱 GitHub 上的 Microsoft 驗證連結庫

設定 Azure Active Directory B2C 租使用者

若要執行範例專案,您必須建立 Azure Active Directory B2C 租使用者。 如需詳細資訊,請參閱在 Azure 入口網站 中建立 Azure Active Directory B2C 租使用者。

建立租用戶之後,您需要租用戶名稱和租使用者標識碼來設定行動應用程式。 租用戶標識碼和名稱是由您在建立租使用者 URL 時產生的網域所定義。 如果您產生的租使用者 URL 是https://contoso20190410tenant.onmicrosoft.com/租使用者識別碼contoso20190410tenant.onmicrosoft.com租使用者名稱contoso20190410tenant。 單擊頂端功能表中的目錄和訂用帳戶篩選,在 Azure 入口網站 中尋找租用戶網域。 下列螢幕快照顯示 Azure 目錄和訂用帳戶篩選按鈕和租使用者網域:

Azure 目錄和訂用帳戶篩選檢視中的租用戶名稱

在範例專案中,編輯 Constants.cs 檔案來設定 tenantNametenantId 欄位。 下列程式代碼示範如果您的租使用者網域為 https://contoso20190410tenant.onmicrosoft.com/,請將這些值取代為入口網站中的值:

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    ...
}

向 Azure Active Directory B2C 註冊行動應用程式

行動應用程式必須先向租用戶註冊,才能連線及驗證使用者。 註冊程式會將唯 一的應用程式標識碼 指派給應用程式,以及 將響應導向回應用程式驗證之後的重新導向 URL 。 如需詳細資訊,請參閱 Azure Active Directory B2C:註冊您的應用程式。 您必須知道 指派給應用程式的應用程式識別碼 ,這會列在屬性檢視中的應用程式名稱之後。 下列螢幕快照顯示尋找應用程式識別碼的位置:

Azure 應用程式屬性檢視中的應用程式識別碼

Microsoft 驗證連結庫預期應用程式的重新導向 URL 前面會加上 “msal” 文字,後面接著名為 “auth” 的端點。 如果應用程式識別碼是 「1234abcd」,則完整的網址應該是 msal1234abcd://auth。 請確定您的應用程式已啟用 Native 用戶端設定,並使用您的應用程式識別碼建立自訂重新導向 URI,如下列螢幕快照所示:

Azure 應用程式屬性檢視中的自定義重新導向 URI

稍後會在 Android ApplicationManifest.xml 和 iOS Info.plist 中使用 URL。

在範例專案中,編輯 Constants.cs 檔案,將字段設定 clientId 為您的應用程式 識別碼。 下列程式代碼顯示如果您的應用程式識別碼為 1234abcd,則應該如何設定此值:

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    static readonly string clientId = "1234abcd";
    ...
}

建立註冊和登入原則,以及忘記密碼原則

原則是使用者完成工作的體驗,例如建立帳戶或重設密碼。 原則也會指定當使用者從體驗傳回時,應用程式收到的令牌內容。 您必須設定帳戶註冊和登入的原則,以及重設密碼。 Azure 具有內建原則,可簡化常見原則的建立。 如需詳細資訊,請參閱 Azure Active Directory B2C:內建原則

當您完成原則設定時,應該會在 Azure 入口網站 的 [使用者流程] 檢視中有兩個原則。 下列螢幕快照示範 Azure 入口網站 中兩個已設定的原則:

Azure 使用者流程中已設定的兩個原則(原則) 檢視

在範例專案中,編輯 Constants.cs 檔案來設定 policySigninpolicyPassword 欄位,以反映您在原則設定期間選擇的名稱:

public static class Constants
{
    static readonly string tenantName = "contoso20190410tenant";
    static readonly string tenantId = "contoso20190410tenant.onmicrosoft.com";
    static readonly string clientId = "1234abcd";
    static readonly string policySignin = "B2C_1_signupsignin1";
    static readonly string policyPassword = "B2C_1_passwordreset";
    ...
}

使用 Microsoft 驗證連結庫 (MSAL) 進行驗證

Microsoft 驗證連結庫 (MSAL) NuGet 套件必須新增至共用的 .NET Standard 專案,以及方案中的平台專案 Xamarin.Forms 。 MSAL 包含一個 PublicClientApplicationBuilder 類別,可建構遵守 介面的物件 IPublicClientApplication 。 MSAL 會 With 利用 子句來提供建構函式和驗證方法的其他參數。

在範例專案中,App.xaml 的程式代碼會定義名為 AuthenticationClientUIParent的靜態屬性,並在建構函式中具現化 AuthenticationClient 物件。 子 WithIosKeychainSecurityGroup 句提供 iOS 應用程式的安全組名稱。 子 WithB2CAuthority 句會提供將用來驗證用戶的預設 Authority 或原則。 子 WithRedirectUri 句會告訴 Azure 通知中樞實例,如果指定多個 URI,則會使用重新導向 URI。 下列範例示範如何具現化 PublicClientApplication

public partial class App : Application
{
    public static IPublicClientApplication AuthenticationClient { get; private set; }

    public static object UIParent { get; set; } = null;

    public App()
    {
        InitializeComponent();

        AuthenticationClient = PublicClientApplicationBuilder.Create(Constants.ClientId)
            .WithIosKeychainSecurityGroup(Constants.IosKeychainSecurityGroups)
            .WithB2CAuthority(Constants.AuthoritySignin)
            .WithRedirectUri($"msal{Constants.ClientId}://auth")
            .Build();

        MainPage = new NavigationPage(new LoginPage());
    }

    ...

注意

如果您的 Azure 通知中樞實例只定義了一個重新導向 URI, AuthenticationClient 則實例可以運作,而不需使用 WithRedirectUri 子句來指定重新導向 URI。 不過,如果您的 Azure 組態擴充以支援其他客戶端或驗證方法,您應該一律指定此值。

OnAppearing LoginPage.xaml.cs程式代碼後置AcquireTokenSilentAsync呼叫中的事件處理程式,以重新整理先前登入的使用者驗證令牌。 如果成功,驗證程式會重新導向至 LogoutPage ,且不會在失敗時執行任何動作。 下列範例顯示 中的 OnAppearing無訊息重新驗證程式:

public partial class LoginPage : ContentPage
{
    ...

    protected override async void OnAppearing()
    {
        try
        {
            // Look for existing account
            IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();

            AuthenticationResult result = await App.AuthenticationClient
                .AcquireTokenSilent(Constants.Scopes, accounts.FirstOrDefault())
                .ExecuteAsync();

            await Navigation.PushAsync(new LogoutPage(result));
        }
        catch
        {
            // Do nothing - the user isn't logged in
        }
        base.OnAppearing();
    }

    ...
}

OnLoginButtonClicked事件處理程式(按兩下[登入] 按鈕時引發)呼叫 AcquireTokenAsync。 MSAL 連結庫會自動開啟行動裝置瀏覽器,並流覽至登入頁面。 名為 Authority 的登入 URL 是Constants.cs檔案中定義的租使用者名稱和原則的組合。 如果使用者選擇忘記密碼選項,則會傳回應用程式,但例外狀況會啟動忘記的密碼體驗。 下列範例顯示驗證程式:

public partial class LoginPage : ContentPage
{
    ...

    async void OnLoginButtonClicked(object sender, EventArgs e)
    {
        AuthenticationResult result;
        try
        {
            result = await App.AuthenticationClient
                .AcquireTokenInteractive(Constants.Scopes)
                .WithPrompt(Prompt.SelectAccount)
                .WithParentActivityOrWindow(App.UIParent)
                .ExecuteAsync();

            await Navigation.PushAsync(new LogoutPage(result));
        }
        catch (MsalException ex)
        {
            if (ex.Message != null && ex.Message.Contains("AADB2C90118"))
            {
                result = await OnForgotPassword();
                await Navigation.PushAsync(new LogoutPage(result));
            }
            else if (ex.ErrorCode != "authentication_canceled")
            {
                await DisplayAlert("An error has occurred", "Exception message: " + ex.Message, "Dismiss");
            }
        }
    }

    ...
}

方法 OnForgotPassword 類似於登入程式,但會實作自定義原則。 OnForgotPassword 會使用不同的 多載 AcquireTokenAsync,可讓您提供特定的 授權單位。 下列範例示範如何在取得權杖時提供自訂 授權單位

public partial class LoginPage : ContentPage
{
    ...
    async Task<AuthenticationResult> OnForgotPassword()
    {
        try
        {
            return await App.AuthenticationClient
                .AcquireTokenInteractive(Constants.Scopes)
                .WithPrompt(Prompt.SelectAccount)
                .WithParentActivityOrWindow(App.UIParent)
                .WithB2CAuthority(Constants.AuthorityPasswordReset)
                .ExecuteAsync();
        }
        catch (MsalException)
        {
            // Do nothing - ErrorCode will be displayed in OnLoginButtonClicked
            return null;
        }
    }
}

最後一項驗證是註銷程式。 當使用者 OnLogoutButtonClicked 按下註銷按鈕時,會呼叫 方法。 它會迴圈執行所有帳戶,並確保其令牌已失效。 下列範例示範註銷實作:

public partial class LogoutPage : ContentPage
{
    ...
    async void OnLogoutButtonClicked(object sender, EventArgs e)
    {
        IEnumerable<IAccount> accounts = await App.AuthenticationClient.GetAccountsAsync();

        while (accounts.Any())
        {
            await App.AuthenticationClient.RemoveAsync(accounts.First());
            accounts = await App.AuthenticationClient.GetAccountsAsync();
        }

        await Navigation.PopAsync();
    }
}

iOS

在 iOS 上,向 Azure Active Directory B2C 註冊的自定義 URL 配置必須在 Info.plist註冊。 MSAL 預期 URL 配置必須遵守特定模式,如先前在向 Azure Active Directory B2C 註冊行動應用程式中所述。 下列螢幕快照顯示 Info.plist 中的自訂 URL 配置。

「在 iOS 上註冊自定義 URL 配置」

MSAL 也需要 iOS 上的 Keychain 權利,已在 Entitilements.plist註冊,如下列螢幕快照所示:

「在 iOS 上設定應用程式權利」

當 Azure Active Directory B2C 完成授權要求時,它會重新導向至已註冊的重新導向 URL。 自定義 URL 配置會導致 iOS 啟動行動應用程式,並傳入 URL 做為啟動參數,其中會由 OpenUrl 應用程式的 AppDelegate 類別覆寫處理,並將體驗的控制傳回 MSAL。 實 OpenUrl 作會顯示在下列程式代碼範例中:

using Microsoft.Identity.Client;

namespace TodoAzure.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        ...
        public override bool OpenUrl(UIApplication app, NSUrl url, NSDictionary options)
        {
            AuthenticationContinuationHelper.SetAuthenticationContinuationEventArgs(url);
            return base.OpenUrl(app, url, options);
        }
    }
}

Android

在 Android 上,向 Azure Active Directory B2C 註冊的自定義 URL 配置必須在AndroidManifest.xml註冊。 MSAL 預期 URL 配置必須遵守特定模式,如先前在向 Azure Active Directory B2C 註冊行動應用程式中所述。 下列範例顯示AndroidManifest.xml中的自定義 URL 配置。

<?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.xamarin.adb2cauthorization">
  <uses-sdk android:minSdkVersion="15" />
  <application android:label="ADB2CAuthorization">
    <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" />
        <!-- example -->
        <!-- <data android:scheme="msalaaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" android:host="auth" /> -->
        <data android:scheme="INSERT_URI_SCHEME_HERE" android:host="auth" />
      </intent-filter>
    </activity>"
  </application>
</manifest>

類別MainActivity必須經過修改,才能在呼叫期間OnCreate將 物件提供給UIParent應用程式。 當 Azure Active Directory B2C 完成授權要求時,它會從AndroidManifest.xml重新導向至已註冊的 URL 配置。 已註冊的 URI 配置會導致 Android 使用 OnActivityResult URL 呼叫 方法做為啟動參數,其中由 SetAuthenticationContinuationEventArgs 方法處理。

public class MainActivity : FormsAppCompatActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(bundle);

        Forms.Init(this, bundle);
        LoadApplication(new App());
        App.UIParent = this;
    }

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

通用 Windows 平台

不需要額外的設定,即可在 通用 Windows 平台 上使用 MSAL

執行專案

在虛擬或實體裝置上執行應用程式。 點選 [ 登入 ] 按鈕應該會開啟瀏覽器,並流覽至您可以登入或建立帳戶的頁面。 完成登入程式之後,您應該會返回應用程式的註銷頁面。 下列螢幕快照顯示 Android 和 iOS 上執行的使用者登入畫面:

「Android 和 iOS 上的 Azure ADB2C 登入畫面」