Povolení ověřování ve vlastní aplikaci pro Android pomocí Azure AD B2C

V tomto článku se dozvíte, jak přidat ověřování Azure Active Directory B2C (Azure AD B2C) do vlastní mobilní aplikace pro Android.

V tomto článku můžete nakonfigurovat ověřování v ukázkové aplikaci pro Android pomocí Azure AD B2C a nahradit ukázkovou aplikaci pro Android vlastní aplikací pro Android. Po dokončení pokynů v tomto článku vaše aplikace přijme přihlášení prostřednictvím Azure AD B2C.

Předpoklady

Projděte si požadavky a pokyny k integraci v tématu Konfigurace ověřování v ukázkové aplikaci pro Android pomocí Azure AD B2C.

Vytvoření projektu aplikace pro Android

Pokud ještě nemáte aplikaci pro Android, nastavte nový projekt následujícím způsobem:

  1. V Android Studiu vyberte Spustit nový projekt Android Studio.
  2. Vyberte základní aktivitu a pak vyberte Další.
  3. Pojmenujte svoji aplikaci.
  4. Uložte název balíčku. Později ho zadáte na webu Azure Portal.
  5. Změňte jazyk z Kotlin na Javu.
  6. Nastavte minimální úroveň rozhraní API na rozhraní API 19 nebo vyšší a pak vyberte Dokončit.
  7. V zobrazení projektu zvolte v rozevíracím seznamu Projekt , abyste zobrazili zdrojové a nesourcové soubory projektu, otevřeli aplikaci/build.gradle a pak nastavili targetSdkVersion na 28.

Krok 1: Instalace závislostí

V okně projektu Android Studio přejděte do souboru app>build.gradle a přidejte následující:

apply plugin: 'com.android.application'

allprojects {
    repositories {
    mavenCentral()
    google()
    mavenLocal()
    maven {
        url 'https://pkgs.dev.azure.com/MicrosoftDeviceSDK/DuoSDK-Public/_packaging/Duo-SDK-Feed/maven/v1'
    }
    maven {
        name "vsts-maven-adal-android"
        url "https://identitydivision.pkgs.visualstudio.com/_packaging/AndroidADAL/maven/v1"
        credentials {
            username System.getenv("ENV_VSTS_MVN_ANDROIDADAL_USERNAME") != null ? System.getenv("ENV_VSTS_MVN_ANDROIDADAL_USERNAME") : project.findProperty("vstsUsername")
            password System.getenv("ENV_VSTS_MVN_ANDROIDADAL_ACCESSTOKEN") != null ? System.getenv("ENV_VSTS_MVN_ANDROIDADAL_ACCESSTOKEN") : project.findProperty("vstsMavenAccessToken")
        }
    }
    jcenter()
    }
}
dependencies{
    implementation 'com.microsoft.identity.client:msal:2.+'
    }
packagingOptions{
    exclude("META-INF/jersey-module-version")
}

Krok 2: Přidání komponent ověřování

Vzorový kód se skládá z následujících komponent. Přidejte tyto komponenty z ukázkové aplikace pro Android do vlastní aplikace.

Komponenta Typ Source Popis
B2CUser Třída KotlinJava Představuje uživatele B2C. Tato třída umožňuje uživatelům přihlásit se pomocí více zásad.
B2CModeFragment Fragment – třída KotlinJava Fragment představuje modulární část přihlášení pomocí uživatelského rozhraní Azure AD B2C v rámci hlavní aktivity. Tento fragment obsahuje většinu ověřovacího kódu.
fragment_b2c_mode.xml Rozložení fragmentu KotlinJava Definuje strukturu pro uživatelské rozhraní pro komponentu fragmentu B2CModeFragment.
B2CConfiguration Třída KotlinJava Konfigurační soubor obsahuje informace o vašem zprostředkovateli identity Azure AD B2C. Mobilní aplikace tyto informace používá k vytvoření vztahu důvěryhodnosti s Azure AD B2C, přihlášení a odhlášení uživatelů, získání tokenů a jejich ověření. Další nastavení konfigurace najdete v souboru auth_config_b2c.json.
auth_config_b2c.json Soubor JSON KotlinJava Konfigurační soubor obsahuje informace o vašem zprostředkovateli identity Azure AD B2C. Mobilní aplikace tyto informace používá k vytvoření vztahu důvěryhodnosti s Azure AD B2C, přihlášení a odhlášení uživatelů, získání tokenů a jejich ověření. Další nastavení konfigurace najdete ve třídě B2CConfiguration.

Krok 3: Konfigurace aplikace pro Android

Po přidání komponent ověřování nakonfigurujte aplikaci pro Android pomocí nastavení Azure AD B2C. Nastavení zprostředkovatele identity Azure AD B2C se konfiguruje v souboru auth_config_b2c.json a třídě B2CConfiguration.

Pokyny najdete v tématu Konfigurace ukázkové mobilní aplikace.

Krok 4: Nastavení identifikátoru URI přesměrování

Nakonfigurujte, kde vaše aplikace naslouchá odpovědi tokenu Azure AD B2C.

  1. Vygenerujte novou hodnotu hash vývojového podpisu. To se změní pro každé vývojové prostředí.

    Ve Windows:

    keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64
    

    Pro iOS:

    keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore | openssl sha1 -binary | openssl base64
    

    V produkčním prostředí použijte následující příkaz:

    keytool -exportcert -alias SIGNATURE_ALIAS -keystore PATH_TO_KEYSTORE | openssl sha1 -binary | openssl base64
    

    Další nápovědu k podepisování aplikací najdete v tématu Podepsání aplikace pro Android.

  2. Vyberte hlavní>soubor AndroidManifest.xml aplikace>>a pak do textu aplikace přidejte následující BrowserTabActivity aktivitu:

    <!--Intent filter to capture System Browser or Authenticator calling back to our app after sign-in-->
    <activity
        android:name="com.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="Package_Name"
                android:path="/Signature_Hash" />
        </intent-filter>
    </activity>
    
  3. Nahraďte Signature_Hash hodnotu hash, kterou jste vygenerovali.

  4. Nahraďte Package_Name názvem balíčku pro Android.

Pokud chcete aktualizovat registraci mobilní aplikace pomocí identifikátoru URI přesměrování aplikace, postupujte takto:

  1. Přihlaste se k portálu Azure.
  2. Pokud máte přístup k více tenantům, v horní nabídce vyberte ikonu Nastavení a v nabídce Adresáře a předplatná přepněte do svého tenanta Azure AD B2C.
  3. Vyhledejte a vyberte Azure AD B2C.
  4. Vyberte Registrace aplikací a pak vyberte aplikaci, kterou jste zaregistrovali v kroku 2.3: Registrace mobilní aplikace.
  5. Vyberte Ověřování.
  6. V části Android vyberte Přidat identifikátor URI.
  7. Zadejte název balíčku a hodnotu hash podpisu.
  8. Zvolte Uložit.

Identifikátor URI přesměrování a BrowserTabActivity aktivita by měla vypadat podobně jako v následující ukázce:

Adresa URL pro přesměrování ukázkového Androidu vypadá takto:

msauth://com.azuresamples.msalandroidkotlinapp/1wIqXSqBj7w%2Bh11ZifsnqwgyKrY%3D

Filtr záměru používá stejný vzor, jak je znázorněno v následujícím fragmentu kódu XML:

<activity android:name="com.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:host="com.azuresamples.msalandroidkotlinapp"
            android:path="/1wIqXSqBj7w+h11ZifsnqwgyKrY="
            android:scheme="msauth" />
    </intent-filter>
</activity>

Krok 5: Přizpůsobení stavebních bloků kódu

Tato část popisuje stavební bloky kódu, které umožňují ověřování pro vaši aplikaci pro Android. Následující tabulka uvádí metody B2CModeFragment a postup přizpůsobení kódu.

Krok 5.1: Vytvoření instance veřejné klientské aplikace

Veřejné klientské aplikace nejsou důvěryhodné, aby bezpečně uchovávali tajné kódy aplikací a nemají tajné kódy klienta. V onCreate nebo onCreateView vytvořte instanci knihovny MSAL pomocí objektu veřejné klientské aplikace s více účty.

Třída MultipleAccountPublicClientApplication se používá k vytváření aplikací založených na MSAL, které umožňují přihlášení více účtů najednou. Třída umožňuje přihlášení s několika toky uživatelů Azure AD B2C nebo vlastními zásadami. Například uživatelé se přihlašují pomocí toku uživatele pro registraci nebo přihlášení a později spustí tok uživatele profilu úprav.

Následující fragment kódu ukazuje, jak inicializovat knihovnu MSAL s konfiguračním souborem auth_config_b2c.json JSON.

PublicClientApplication.createMultipleAccountPublicClientApplication(context!!,
    R.raw.auth_config_b2c,
    object : IMultipleAccountApplicationCreatedListener {
        override fun onCreated(application: IMultipleAccountPublicClientApplication) {
            // Set the MultipleAccountPublicClientApplication to the class member b2cApp
            b2cApp = application
            // Load the account (if there is any)
            loadAccounts()
        }

        override fun onError(exception: MsalException) {
            // Error handling
            displayError(exception)
        }
    })

Krok 5.2: Načtení účtů

Když se aplikace dostane do popředí, aplikace načte existující účet, aby určila, jestli jsou uživatelé přihlášení. Tuto metodu použijte k aktualizaci uživatelského rozhraní se stavem ověřování. Můžete například povolit nebo zakázat tlačítko odhlášení.

Následující fragment kódu ukazuje, jak načíst účty.

private fun loadAccounts() {
    if (b2cApp == null) {
        return
    }
    b2cApp!!.getAccounts(object : LoadAccountsCallback {
        override fun onTaskCompleted(result: List<IAccount>) {
            users = B2CUser.getB2CUsersFromAccountList(result)
            updateUI(users)
        }
    
        override fun onError(exception: MsalException) {
            displayError(exception)
        }
    })
    }

Krok 5.3: Spuštění interaktivní žádosti o autorizaci

Interaktivní žádost o autorizaci je tok, ve kterém se uživatelům zobrazí výzva k registraci nebo přihlášení. Metoda initializeUI nakonfiguruje runUserFlowButton událost kliknutí. Když uživatelé vyberou tlačítko Spustit tok uživatele, aplikace je přenese do Azure AD B2C a dokončí tok přihlášení.

Metoda runUserFlowButton.setOnClickListener připraví objekt s relevantními daty AcquireTokenParameters o autorizační žádosti. Metoda acquireToken pak vyzve uživatele, aby dokončili tok registrace nebo přihlášení.

Následující fragment kódu ukazuje, jak spustit interaktivní žádost o autorizaci:

val parameters = AcquireTokenParameters.Builder()
        .startAuthorizationFromActivity(activity)
        .fromAuthority(getAuthorityFromPolicyName(policy_list.getSelectedItem().toString()))
        .withScopes(B2CConfiguration.scopes)
        .withPrompt(Prompt.LOGIN)
        .withCallback(authInteractiveCallback)
        .build()

b2cApp!!.acquireToken(parameters)

Krok 5.4: Vytvoření zpětného volání žádosti o interaktivní autorizaci

Po dokončení autorizačního toku, ať už úspěšně nebo neúspěšně, se výsledek vrátí do metody zpětného getAuthInteractiveCallback() volání.

Metoda zpětného AuthenticationResult volání předá objekt nebo chybovou zprávu v objektu MsalException . Tuto metodu použijte k:

  • Po dokončení přihlášení aktualizujte uživatelské rozhraní mobilní aplikace informacemi.
  • Znovu načtěte objekt účtů.
  • Volání služby webového rozhraní API pomocí přístupového tokenu
  • Zpracování chyb ověřování

Následující fragment kódu ukazuje použití zpětného volání interaktivního ověřování.

private val authInteractiveCallback: AuthenticationCallback
    private get() = object : AuthenticationCallback {
        override fun onSuccess(authenticationResult: IAuthenticationResult) {
            /* Successfully got a token, use it to call a protected resource; web API  */
            Log.d(TAG, "Successfully authenticated")

            /* display result info */
            displayResult(authenticationResult)

            /* Reload account asynchronously to get the up-to-date list. */
            loadAccounts()
        }

        override fun onError(exception: MsalException) {
            val B2C_PASSWORD_CHANGE = "AADB2C90118"
            if (exception.message!!.contains(B2C_PASSWORD_CHANGE)) {
                txt_log!!.text = """
                    Users click the 'Forgot Password' link in a sign-up or sign-in user flow.
                    Your application needs to handle this error code by running a specific user flow that resets the password.
                    """.trimIndent()
                return
            }

            /* Failed to acquireToken */Log.d(TAG, "Authentication failed: $exception")
            displayError(exception)
            if (exception is MsalClientException) {
                /* Exception inside MSAL, more info inside MsalError.java */
            } else if (exception is MsalServiceException) {
                /* Exception when communicating with the STS, likely config issue */
            }
        }

        override fun onCancel() {
            /* User canceled the authentication */
            Log.d(TAG, "User cancelled login.")
        }
    }

Krok 6: Volání webového rozhraní API

Aby bylo potřeba volat webové rozhraní API pro autorizaci založené na tokenech, musí mít aplikace platný přístupový token. Aplikace provede následující:

  1. Získá přístupový token s požadovanými oprávněními (obory) pro koncový bod webového rozhraní API.
  2. Předá přístupový token jako nosný token v autorizační hlavičce požadavku HTTP pomocí tohoto formátu:
Authorization: Bearer <access-token>

Když se uživatelé přihlásí interaktivně, aplikace získá přístupový token v metodě zpětného getAuthInteractiveCallback volání. Pro po sobě jdoucí volání webového rozhraní API použijte bezobslužnou proceduru získání tokenu, jak je popsáno v této části.

Před voláním webového rozhraní API zavolejte metodu acquireTokenSilentAsync s příslušnými obory pro koncový bod webového rozhraní API. Knihovna MSAL provede následující:

  1. Pokusí se načíst přístupový token s požadovanými obory z mezipaměti tokenů. Pokud token existuje, vrátí se token.
  2. Pokud token není v mezipaměti tokenů, služba MSAL se pokusí použít obnovovací token k získání nového tokenu.
  3. Pokud obnovovací token neexistuje nebo vypršela jeho platnost, vrátí se výjimka. Doporučujeme vyzvat uživatele, aby se přihlásil interaktivně.

Následující fragment kódu ukazuje, jak získat přístupový token:

Událost acquireTokenSilentButton kliknutí na tlačítko získá přístupový token se zadanými obory.

btn_acquireTokenSilently.setOnClickListener(View.OnClickListener {
    if (b2cApp == null) {
        return@OnClickListener
    }
    val selectedUser = users!![user_list.getSelectedItemPosition()]
    selectedUser.acquireTokenSilentAsync(b2cApp!!,
            policy_list.getSelectedItem().toString(),
            B2CConfiguration.scopes,
            authSilentCallback)
})

Metoda authSilentCallback zpětného volání vrátí přístupový token a volá webové rozhraní API:

private val authSilentCallback: SilentAuthenticationCallback
    private get() = object : SilentAuthenticationCallback {
        override fun onSuccess(authenticationResult: IAuthenticationResult) {
            Log.d(TAG, "Successfully authenticated")

            /* Call your web API here*/
            callWebAPI(authenticationResult)
        }

        override fun onError(exception: MsalException) {
            /* Failed to acquireToken */
            Log.d(TAG, "Authentication failed: $exception")
            displayError(exception)
            if (exception is MsalClientException) {
                /* Exception inside MSAL, more info inside MsalError.java */
            } else if (exception is MsalServiceException) {
                /* Exception when communicating with the STS, likely config issue */
            } else if (exception is MsalUiRequiredException) {
                /* Tokens expired or no session, retry with interactive */
            }
        }
    }

Následující příklad ukazuje, jak volat chráněné webové rozhraní API s nosným tokenem:

@Throws(java.lang.Exception::class)
private fun callWebAPI(authenticationResult: IAuthenticationResult) {
    val accessToken = authenticationResult.accessToken
    val thread = Thread {
        try {
            val url = URL("https://your-app-service.azurewebsites.net/helo")
            val conn = url.openConnection() as HttpsURLConnection
            conn.setRequestProperty("Accept", "application/json")
            
            // Set the bearer token
            conn.setRequestProperty("Authorization", "Bearer $accessToken")
            if (conn.responseCode == HttpURLConnection.HTTP_OK) {
                val br = BufferedReader(InputStreamReader(conn.inputStream))
                var strCurrentLine: String?
                while (br.readLine().also { strCurrentLine = it } != null) {
                    Log.d(TAG, strCurrentLine)
                }
            }
            conn.disconnect()
        } catch (e: IOException) {
            e.printStackTrace()
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    thread.start()
}

Přidání oprávnění k provádění síťových operací

Pokud chcete v aplikaci provádět síťové operace, přidejte do manifestu následující oprávnění. Další informace najdete v tématu Připojení k síti.

<uses-permission android:name="android.permission.INTERNET"/>

Další kroky

Naučte se: