Mit OpenID Connect auf Android-Geräten authentifizieren

Wenn Sie auf Firebase Authentication with Identity Platform umgestellt haben, können Sie Ihre Nutzer mit Firebase über den OpenID Connect (OIDC)-kompatiblen Anbieter Ihrer Wahl authentifizieren. So können Sie Identitätsanbieter verwenden, die von Firebase nicht nativ unterstützt werden.

Hinweis

Wenn Sie Nutzer über einen OIDC-Anbieter anmelden möchten, müssen Sie zuerst einige Informationen vom Anbieter einholen:

  • Client-ID: Ein eindeutiger String des Anbieters, der Ihre App identifiziert. Ihr Anbieter kann Ihnen für jede unterstützte Plattform eine andere Client-ID zuweisen. Dies ist einer der Werte des Anspruchs aud in ID-Tokens, die von Ihrem Anbieter ausgestellt wurden.

  • Clientschlüssel: Ein geheimer String, mit dem der Anbieter die Inhaberschaft einer Client-ID bestätigt. Für jede Client-ID ist ein passender Clientschlüssel erforderlich. Dieser Wert ist nur erforderlich, wenn Sie den Autorisierungs-Code-Prozess verwenden, was wir dringend empfehlen.

  • Aussteller: Ein String, der Ihren Anbieter identifiziert. Dieser Wert muss eine URL sein, die mit /.well-known/openid-configuration angehängt den Speicherort des OIDC-Discovery-Dokuments des Anbieters angibt. Wenn der Aussteller beispielsweise https://auth.example.com ist, muss das Discovery-Dokument unter https://auth.example.com/.well-known/openid-configuration verfügbar sein.

Nachdem Sie die oben genannten Informationen haben, aktivieren Sie OpenID Connect als Anmeldeanbieter für Ihr Firebase-Projekt:

  1. Fügen Sie Ihrem Android-Projekt Firebase hinzu.

  2. Wenn Sie noch nicht auf Firebase Authentication with Identity Platform umgestellt haben, tun Sie dies. Die OpenID Connect-Authentifizierung ist nur in Projekten verfügbar, die auf die neue Version umgestellt wurden.

  3. Klicken Sie auf der Seite Anbieter für Anmeldungen der Firebase-Konsole auf Neuen Anbieter hinzufügen und dann auf OpenID Connect.

  4. Wählen Sie aus, ob Sie den Autorisierungscode-Vorgang oder den Vorgang für die implizite Berechtigung verwenden möchten.

    Sie sollten immer den Codeablauf verwenden, wenn Ihr Anbieter dies unterstützt. Der implizite Ablauf ist weniger sicher und wird daher nicht empfohlen.

  5. Geben Sie einen Namen für diesen Anbieter ein. Notieren Sie sich die generierte Anbieter-ID, z. B. oidc.example-provider. Sie benötigen diese ID, wenn Sie Ihrer App einen Anmeldencode hinzufügen.

  6. Geben Sie Ihre Client-ID und Ihr Client-Secret sowie den Aussteller-String Ihres Anbieters an. Diese Werte müssen genau mit den Werten übereinstimmen, die Ihnen Ihr Anbieter zugewiesen hat.

  7. Speichern Sie die Änderungen.

Anmeldevorgang mit dem Firebase SDK abwickeln

Wenn Sie eine Android-App entwickeln, ist die einfachste Möglichkeit, Ihre Nutzer mit Firebase über Ihren OIDC-Anbieter zu authentifizieren, die gesamte Anmeldeabfolge mit dem Firebase Android SDK zu verarbeiten.

So verwalten Sie den Anmeldevorgang mit dem Firebase Android SDK:

  1. Instanz eines OAuthProvider mit dem Builder und der ID des Anbieters erstellen

    Kotlin

    val providerBuilder = OAuthProvider.newBuilder("oidc.example-provider")

    Java

    OAuthProvider.Builder providerBuilder = OAuthProvider.newBuilder("oidc.example-provider");

  2. Optional: Geben Sie zusätzliche benutzerdefinierte OAuth-Parameter an, die mit der OAuth-Anfrage gesendet werden sollen.

    Kotlin

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com")

    Java

    // Target specific email with login hint.
    providerBuilder.addCustomParameter("login_hint", "user@example.com");

    Erkundigen Sie sich bei Ihrem OIDC-Anbieter, welche Parameter er unterstützt. Hinweis: Sie können keine für Firebase erforderlichen Parameter mit setCustomParameters() übergeben. Diese Parameter sind client_id, response_type, redirect_uri, state, scope und response_mode.

  3. Optional: Geben Sie zusätzliche OAuth 2.0-Bereiche an, die über das Basisprofil hinausgehen und die Sie vom Authentifizierungsanbieter anfordern möchten.

    Kotlin

    // Request read access to a user's email addresses.
    // This must be preconfigured in the app's API permissions.
    providerBuilder.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");
                }
            };
    providerBuilder.setScopes(scopes);

    Erkundigen Sie sich bei Ihrem OIDC-Anbieter nach den verwendeten Bereichen.

  4. Authentifizierung mit Firebase über das OAuth-Anbieterobjekt Im Gegensatz zu anderen FirebaseAuth-Vorgängen wird hier die Kontrolle über die Benutzeroberfläche übernommen, indem ein benutzerdefinierter Chrome-Tab eingeblendet wird. Daher sollten Sie in den angehängten OnSuccessListener und OnFailureListener nicht auf Ihre Aktivität verweisen. Sie werden sofort getrennt, wenn der Vorgang die Benutzeroberfläche startet.

    Prüfen Sie zuerst, ob Sie bereits eine Antwort erhalten haben. Bei der Anmeldung mit dieser Methode werden Ihre Aktivitäten im Hintergrund ausgeführt, was bedeutet, dass sie während des Anmeldevorgangs vom System zurückgerufen werden können. Damit der Nutzer nicht noch einmal versuchen muss, sollten Sie prüfen, ob ein Ergebnis bereits vorhanden ist.

    Wenn Sie prüfen möchten, ob ein ausstehendes Ergebnis vorliegt, rufen Sie getPendingAuthResult auf:

    Kotlin

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

    Rufe startActivityForSignInWithProvider auf, um den Anmeldevorgang zu starten:

    Kotlin

    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.
                        }
                    });

  5. In den obigen Beispielen liegt der Schwerpunkt auf den Anmeldeabläufen. Sie können einen OIDC-Anbieter aber auch über startActivityForLinkWithProvider mit einem vorhandenen Nutzer verknüpfen. Sie können beispielsweise mehrere Anbieter mit demselben Nutzer verknüpfen, damit er sich mit einem beliebigen davon anmelden kann.

    Kotlin

    // 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. Dasselbe Muster kann mit startActivityForReauthenticateWithProvider verwendet werden, um aktuelle Anmeldedaten für vertrauliche Vorgänge abzurufen, für die eine aktuelle Anmeldung erforderlich ist.

    Kotlin

    // 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.
                        }
                    });

Anmeldevorgang manuell verarbeiten

Wenn Sie den OpenID Connect-Anmeldevorgang bereits in Ihrer App implementiert haben, können Sie das ID-Token direkt zur Authentifizierung bei Firebase verwenden:

Kotlin

val providerId = "oidc.example-provider" // As registered in Firebase console.
val credential = oAuthCredential(providerId) {
    setIdToken(idToken) // ID token from OpenID Connect flow.
}
Firebase.auth
    .signInWithCredential(credential)
    .addOnSuccessListener { authResult ->
        // User is signed in.

        // IdP data available in:
        //    authResult.additionalUserInfo.profile
    }
    .addOnFailureListener { e ->
        // Handle failure.
    }

Java

AuthCredential credential = OAuthProvider
        .newCredentialBuilder("oidc.example-provider")  // As registered in Firebase console.
        .setIdToken(idToken)  // ID token from OpenID Connect flow.
        .build();
FirebaseAuth.getInstance()
        .signInWithCredential(credential)
        .addOnSuccessListener(new OnSuccessListener<AuthResult>() {
            @Override
            public void onSuccess(AuthResult authResult) {
                // User is signed in.

                // IdP data available in:
                //    authResult.getAdditionalUserInfo().getProfile()
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                // Handle failure.
            }
        });

Nächste Schritte

Nachdem sich ein Nutzer zum ersten Mal angemeldet hat, wird ein neues Nutzerkonto erstellt und mit den Anmeldedaten verknüpft, d. h. mit dem Nutzernamen und Passwort, der Telefonnummer oder den Informationen zum Authentifizierungsanbieter, mit denen sich der Nutzer angemeldet hat. Dieses neue Konto wird als Teil Ihres Firebase-Projekts gespeichert und kann verwendet werden, um einen Nutzer in allen Apps in Ihrem Projekt zu identifizieren, unabhängig davon, wie er sich anmeldet.

  • In Ihren Apps können Sie die grundlegenden Profilinformationen des Nutzers über das FirebaseUser-Objekt abrufen. Weitere Informationen finden Sie unter Nutzer verwalten.

  • In Ihren Firebase Realtime Database- und Cloud Storage-Sicherheitsregeln können Sie die eindeutige Nutzer-ID des angemeldeten Nutzers aus der Variablen auth abrufen und damit steuern, auf welche Daten ein Nutzer zugreifen kann.

Sie können Nutzern erlauben, sich über mehrere Authentifizierungsanbieter in Ihrer App anzumelden, indem Sie Anmeldedaten des Authentifizierungsanbieters mit einem vorhandenen Nutzerkonto verknüpfen.

Wenn Sie einen Nutzer abmelden möchten, rufen Sie signOut auf:

Kotlin

Firebase.auth.signOut()

Java

FirebaseAuth.getInstance().signOut();