在 Android 上使用 Microsoft 進行驗證

您可以使用 Firebase SDK 將網頁型一般 OAuth 登入整合至您的應用程式,讓使用者透過 OAuth 供應商 (例如 Microsoft Azure Active Directory) 驗證 Firebase,以執行端對端登入流程。

事前準備

如要使用 Microsoft 帳戶 (Azure Active Directory 和個人 Microsoft 帳戶) 登入使用者,您必須先啟用 Microsoft 做為 Firebase 專案的登入提供者:

  1. 將 Firebase 新增至您的 Android 專案

  2. Firebase 控制台開啟「驗證」專區。
  3. 在「Sign in method」分頁中,啟用「Microsoft」供應商。
  4. 從供應商的 Play 管理中心,新增「用戶端 ID」和「用戶端密鑰」到供應商設定:
    1. 如要註冊 Microsoft OAuth 用戶端,請按照 快速入門導覽課程:使用 Azure Active Directory v2.0 端點註冊應用程式。請注意,這個端點支援使用 Microsoft 個人帳戶和 Azure Active Directory 帳戶登入。 進一步瞭解 Azure Active Directory 2.0 版。
    2. 向這些供應商註冊應用程式時,請務必為專案的 *.firebaseapp.com 網域註冊應用程式的重新導向網域。
  5. 點選「Save」
  6. 如果尚未指定應用程式的 SHA-1 指紋,請前往 Firebase 控制台的設定頁面指定。如要進一步瞭解如何取得應用程式的 SHA-1 指紋,請參閱「驗證用戶端」。

使用 Firebase SDK 處理登入流程

如要建構 Android 應用程式,使用 Microsoft 帳戶透過 Firebase 驗證使用者最簡單的方式,就是透過 Firebase Android SDK 處理整個登入流程。

如要使用 Firebase Android SDK 處理登入流程,請按照下列步驟操作:

  1. 使用 Builder,搭配供應商 ID microsoft.com 建構 OAuthProvider 的執行個體。

    Kotlin+KTX

    val provider = OAuthProvider.newBuilder("microsoft.com")

    Java

    OAuthProvider.Builder provider = OAuthProvider.newBuilder("microsoft.com");

  2. 選用:指定要與 OAuth 要求一起傳送的其他自訂 OAuth 參數。

    Kotlin+KTX

    // Target specific email with login hint.
    // Force re-consent.
    provider.addCustomParameter("prompt", "consent")
    
    // Target specific email with login hint.
    provider.addCustomParameter("login_hint", "user@firstadd.onmicrosoft.com")

    Java

    // Target specific email with login hint.
    // Force re-consent.
    provider.addCustomParameter("prompt", "consent");
    
    // Target specific email with login hint.
    provider.addCustomParameter("login_hint", "user@firstadd.onmicrosoft.com");

    如要瞭解 Microsoft 支援的參數,請參閱 Microsoft OAuth 說明文件。請注意,您無法透過 setCustomParameters() 傳遞 Firebase 所需的參數。這些參數包括 client_idresponse_typeredirect_uristatescoperesponse_mode

    如果只想允許特定 Azure AD 用戶群的使用者登入應用程式,可以使用 Azure AD 用戶群的易記網域名稱或用戶群的 GUID ID。方法是在自訂參數物件中指定「用戶群」欄位。

    Kotlin+KTX

    // Optional "tenant" parameter in case you are using an Azure AD tenant.
    // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or 'contoso.onmicrosoft.com'
    // or "common" for tenant-independent tokens.
    // The default value is "common".
    provider.addCustomParameter("tenant", "TENANT_ID")

    Java

    // Optional "tenant" parameter in case you are using an Azure AD tenant.
    // eg. '8eaef023-2b34-4da1-9baa-8bc8c9d6a490' or 'contoso.onmicrosoft.com'
    // or "common" for tenant-independent tokens.
    // The default value is "common".
    provider.addCustomParameter("tenant", "TENANT_ID");

  3. 選用:指定您要求驗證供應商的基本設定檔以外的其他 OAuth 2.0 範圍。

    Kotlin+KTX

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    provider.scopes = listOf("mail.read", "calendars.read")

    Java

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    List<String> scopes =
            new ArrayList<String>() {
                {
                    add("mail.read");
                    add("calendars.read");
                }
            };
    provider.setScopes(scopes);

    詳情請參閱 Microsoft 權限和同意聲明說明文件

  4. 使用 OAuth 提供者物件向 Firebase 進行驗證。請注意,與其他 FirebaseAuth 作業不同,這會彈出自訂 Chrome 分頁來控制您的 UI。因此,請勿在您附加的 OnSuccessListenerOnFailureListener 中參照活動,因為這些活動會在作業啟動 UI 時立即卸離。

    請先檢查是否已收到回覆。透過此方法登入會將活動置於背景,這表示系統會在登入流程中收回活動。為確保不會讓使用者在發生此情況時再試一次,應檢查結果是否已存在。

    如要查看是否有待處理的結果,請呼叫 getPendingAuthResult

    Kotlin+KTX

    val pendingResultTask = firebaseAuth.pendingAuthResult
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
            .addOnSuccessListener {
                // User is signed in.
                // IdP data available in
                // authResult.getAdditionalUserInfo().getProfile().
                // The OAuth access token can also be retrieved:
                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                // The OAuth secret can be retrieved by calling:
                // ((OAuthCredential)authResult.getCredential()).getSecret().
            }
            .addOnFailureListener {
                // Handle failure.
            }
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    Java

    Task<AuthResult> pendingResultTask = firebaseAuth.getPendingAuthResult();
    if (pendingResultTask != null) {
        // There's something already here! Finish the sign-in for your user.
        pendingResultTask
                .addOnSuccessListener(
                        new OnSuccessListener<AuthResult>() {
                            @Override
                            public void onSuccess(AuthResult authResult) {
                                // User is signed in.
                                // IdP data available in
                                // authResult.getAdditionalUserInfo().getProfile().
                                // The OAuth access token can also be retrieved:
                                // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                                // The OAuth secret can be retrieved by calling:
                                // ((OAuthCredential)authResult.getCredential()).getSecret().
                            }
                        })
                .addOnFailureListener(
                        new OnFailureListener() {
                            @Override
                            public void onFailure(@NonNull Exception e) {
                                // Handle failure.
                            }
                        });
    } else {
        // There's no pending result so you need to start the sign-in flow.
        // See below.
    }

    如要啟動登入流程,請呼叫 startActivityForSignInWithProvider

    Kotlin+KTX

    firebaseAuth
        .startActivityForSignInWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is signed in.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // ((OAuthCredential)authResult.getCredential()).getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    firebaseAuth
            .startActivityForSignInWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is signed in.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // ((OAuthCredential)authResult.getCredential()).getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // ((OAuthCredential)authResult.getCredential()).getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

    成功完成後,您就能從傳回的 OAuthCredential 物件中擷取與供應器相關聯的 OAuth 存取權杖。

    使用 OAuth 存取權杖,您可以呼叫 Microsoft Graph API

    不同於 Firebase 驗證支援的其他供應商,Microsoft 不提供相片網址,而是必須透過 Microsoft Graph API 要求個人資料相片的二進位資料。

    除了 OAuth 存取權杖之外,您也可以透過 OAuthCredential 物件擷取使用者的 OAuth ID 權杖。ID 權杖中的 sub 憑證附加資訊僅適用於應用程式,與 Firebase 驗證使用且可透過 user.getProviderData().get(0).getUid() 存取的聯合使用者 ID 不相符。請改用 oid 憑證附加資訊欄位。使用 Azure AD 用戶群登入時,oid 憑證附加資訊會完全相符。但如果是非用戶群的情況,系統會填補 oid 欄位。如果是聯合 ID 4b2eabcdefghijkloid 會採用形式 00000000-0000-0000-4b2e-abcdefghijkl

  5. 雖然上述範例著重於登入流程,但您也可以使用 startActivityForLinkWithProvider 將 Microsoft 提供者連結至現有使用者。例如,您可以將多個提供者連結至同一位使用者,讓對方透過任一提供者登入。

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForLinkWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // Provider credential is linked to the current user.
            // IdP data available in
            // authResult.getAdditionalUserInfo().getProfile().
            // The OAuth access token can also be retrieved:
            // authResult.getCredential().getAccessToken().
            // The OAuth secret can be retrieved by calling:
            // authResult.getCredential().getSecret().
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForLinkWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // Provider credential is linked to the current user.
                            // IdP data available in
                            // authResult.getAdditionalUserInfo().getProfile().
                            // The OAuth access token can also be retrieved:
                            // authResult.getCredential().getAccessToken().
                            // The OAuth secret can be retrieved by calling:
                            // authResult.getCredential().getSecret().
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

  6. 相同的模式可搭配 startActivityForReauthenticateWithProvider 使用,可針對需要近期登入的敏感作業擷取最新憑證。

    Kotlin+KTX

    // The user is already signed-in.
    val firebaseUser = firebaseAuth.currentUser!!
    firebaseUser
        .startActivityForReauthenticateWithProvider(activity, provider.build())
        .addOnSuccessListener {
            // User is re-authenticated with fresh tokens and
            // should be able to perform sensitive operations
            // like account deletion and email or password
            // update.
        }
        .addOnFailureListener {
            // Handle failure.
        }

    Java

    // The user is already signed-in.
    FirebaseUser firebaseUser = firebaseAuth.getCurrentUser();
    
    firebaseUser
            .startActivityForReauthenticateWithProvider(/* activity= */ this, provider.build())
            .addOnSuccessListener(
                    new OnSuccessListener<AuthResult>() {
                        @Override
                        public void onSuccess(AuthResult authResult) {
                            // User is re-authenticated with fresh tokens and
                            // should be able to perform sensitive operations
                            // like account deletion and email or password
                            // update.
                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            // Handle failure.
                        }
                    });

後續步驟

使用者首次登入時,系統會建立新的使用者帳戶,並連結至憑證 (即使用者名稱與密碼、電話號碼或驗證提供者資訊),也就是使用者登入時使用的憑證。這個新帳戶會儲存在您的 Firebase 專案中,可用來識別專案中各個應用程式的使用者 (無論使用者登入方式為何)。

  • 在應用程式中,您可以透過 FirebaseUser 物件取得使用者的基本個人資料。請參閱 管理使用者一文。

  • 在 Firebase 即時資料庫和 Cloud Storage 安全性規則中,您可以透過 auth 變數取得登入使用者的專屬 ID,並使用該 ID 控管使用者可存取哪些資料。

您可以將驗證供應商憑證連結至現有的使用者帳戶,讓使用者透過多個驗證服務提供者登入您的應用程式。

如要登出使用者,請呼叫 signOut

Kotlin+KTX

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();