TOTP-Multi-Faktor-Authentifizierung für Ihre Android-App hinzufügen

Wenn Sie auf Firebase Authentication with Identity Platform umgestiegen sind, können Sie Ihrer App eine zeitbasierte Multi-Faktor-Authentifizierung (MFA) mit Einmalpasswort (TOTP) hinzufügen.

Firebase Authentication with Identity Platform können Sie ein TOTP als zusätzlichen Faktor für die MFA verwenden. Wenn Sie diese Funktion aktivieren, werden Nutzer, die sich in Ihrer App anmelden möchten, aufgefordert, ein TOTP einzugeben. Dazu müssen sie eine Authenticator App verwenden, die gültige TOTP-Codes generieren kann, z. B. Google Authenticator.

Hinweis

  1. Aktivieren Sie mindestens einen Anbieter, der MFA unterstützt. Alle Anbieter außer den folgenden unterstützen MFA:

    • Telefonauthentifizierung
    • Anonyme Authentifizierung
    • Benutzerdefinierte Authentifizierungstokens
    • Apple Game Center
  2. Achten Sie darauf, dass Ihre App E-Mail-Adressen von Nutzern bestätigt. Die MFA erfordert eine E-Mail-Bestätigung. So wird verhindert, dass sich böswillige Nutzer bei einem Dienst mit einer E-Mail-Adresse registrieren, die ihnen nicht gehört, und dann den tatsächlichen Inhaber der E-Mail-Adresse sperren, indem sie einen zweiten Faktor hinzufügen.

  3. Installieren Sie das Firebase Android SDK, falls noch nicht geschehen.

    Die TOTP-MFA wird nur in der Android SDK-Version 22.1.0 und höher unterstützt.

TOTP-MFA aktivieren

Wenn Sie TOTP als zweiten Faktor aktivieren möchten, verwenden Sie das Admin SDK oder rufen Sie den REST-Endpunkt für die Projekt konfiguration auf.

So verwenden Sie das Admin SDK:

  1. Installieren Sie das Firebase Admin Node.js SDK, falls noch nicht geschehen.

    Die TOTP-MFA wird nur in Firebase Admin Node.js SDK-Version 11.6.0 und höher unterstützt.

  2. Führen Sie den folgenden Befehl aus:

    import { getAuth } from 'firebase-admin/auth';
    
    getAuth().projectConfigManager().updateProjectConfig(
    {
          multiFactorConfig: {
              providerConfigs: [{
                  state: "ENABLED",
                  totpProviderConfig: {
                      adjacentIntervals: NUM_ADJ_INTERVALS
                  }
              }]
          }
    })
    

    Ersetzen Sie Folgendes:

    • NUM_ADJ_INTERVALS: Die Anzahl der angrenzenden Zeitfensterintervalle, aus denen TOTPs akzeptiert werden sollen. Der Wert kann zwischen 0 und 10 liegen. Der Standardwert ist 5.

      Bei TOTPs wird dafür gesorgt, dass zwei Parteien (der Nachweiser und der Validator) innerhalb desselben Zeitfensters (in der Regel 30 Sekunden lang) OTPs generieren und dabei dasselbe Passwort erhalten. Um jedoch die Zeitverschiebung zwischen den Parteien und die Reaktionszeit des Nutzers zu berücksichtigen, können Sie den TOTP-Dienst so konfigurieren, dass er auch TOTPs aus angrenzenden Zeitfenstern akzeptiert.

Führen Sie den folgenden Befehl aus, um die TOTP-MFA über die REST API zu aktivieren:

curl -X PATCH "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=mfa" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    -H "Content-Type: application/json" \
    -H "X-Goog-User-Project: PROJECT_ID" \
    -d \
    '{
        "mfa": {
          "providerConfigs": [{
            "state": "ENABLED",
            "totpProviderConfig": {
              "adjacentIntervals": NUM_ADJ_INTERVALS
            }
          }]
       }
    }'

Ersetzen Sie Folgendes:

  • PROJECT_ID: die Projekt-ID
  • NUM_ADJ_INTERVALS: Die Anzahl der Zeitfensterintervalle. Der Wert kann zwischen 0 und 10 liegen. Der Standardwert ist 5.

    Bei TOTPs wird dafür gesorgt, dass zwei Parteien (der Nachweiser und der Validator) innerhalb desselben Zeitfensters (in der Regel 30 Sekunden lang) OTPs generieren und dabei dasselbe Passwort erhalten. Um jedoch die Zeitverschiebung zwischen den Parteien und die Reaktionszeit des Nutzers zu berücksichtigen, können Sie den TOTP-Dienst so konfigurieren, dass er auch TOTPs aus angrenzenden Zeitfenstern akzeptiert.

Registrierungsmuster auswählen

Sie können auswählen, ob Ihre Anwendung eine Multi-Faktor-Authentifizierung erfordert, und wie und wann Ihre Nutzer registriert werden sollen. Einige gängige Muster sind:

  • Bieten Sie den zweiten Faktor des Nutzers als Teil der Registrierung an. Verwenden Sie diese Methode, wenn Ihre Anwendung eine Multi-Faktor-Authentifizierung für alle Nutzer erfordert.

  • Bieten Sie bei der Registrierung eine überspringbare Option an, mit der ein zweiter Faktor registriert werden kann. Wenn Sie die Multi-Faktor-Authentifizierung in Ihrer App zwar empfehlen, aber nicht erzwingen möchten, können Sie diesen Ansatz verwenden.

  • Ermöglichen Sie, dass ein zweiter Faktor über die Konto- oder Profilverwaltungsseite des Nutzers hinzufügbar ist anstelle über den Anmeldebildschirm. Dadurch wird der Registrierungsprozess vereinfacht und gleichzeitig die Multi-Faktor-Authentifizierung für sicherheitsorientierte Nutzer verfügbar gemacht.

  • Das Hinzufügen eines zweiten Faktors ist erforderlich, wenn der Nutzer auf Features mit höheren Sicherheitsanforderungen zugreifen möchte.

Nutzer für die TOTP-MFA registrieren

Nachdem Sie die TOTP-MFA als zweiten Faktor für Ihre App aktiviert haben, implementieren Sie die clientseitige Logik, um Nutzer für die TOTP-MFA zu registrieren:

  1. Authentifizieren Sie den Nutzer noch einmal.

  2. Generieren Sie ein TOTP-Secret für den authentifizierten Nutzer:

    // Generate a TOTP secret.
    Firebase.auth.currentUser.multiFactor.session
        .addOnSuccessListener { multiFactorSession ->
            TotpMultiFactorGenerator.generateSecret(multiFactorSession)
                .addOnSuccessListener { totpSecret ->
                    // Display the secret to the user and prompt them to
                    // enter it into their authenticator app. (See the next
                    // step.)
                }
        }
    
  3. Zeigen Sie dem Nutzer das Secret an und fordern Sie ihn auf, es in seine Authenticator App einzugeben:

    // Display this key:
    val secret = totpSecret.sharedSecretKey
    

    Neben der Anzeige des Secret-Schlüssels können Sie versuchen, ihn automatisch zur Standard-Authenticator App des Geräts hinzuzufügen. Generieren Sie dazu einen mit Google Authenticator kompatiblen Schlüssel-URI, und übergeben Sie ihn an openInOtpApp():

    val qrCodeUri = totpSecret.generateQrCodeUrl(
        currentUser.email ?: "default account",
        "Your App Name")
    totpSecret.openInOtpApp(qrCodeUri)
    

    Nachdem der Nutzer das Secret zu seiner Authenticator App hinzugefügt hat, werden TOTPs generiert.

  4. Fordern Sie den Nutzer auf, das von seiner Authenticator App angezeigte TOTP einzugeben und damit die MFA-Registrierung abzuschließen:

    // Ask the user for a verification code from the authenticator app.
    val verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    val multiFactorAssertion = TotpMultiFactorGenerator
        .getAssertionForEnrollment(totpSecret, verificationCode)
    Firebase.auth.currentUser.multiFactor.enroll(multiFactorAssertion, "TOTP")
        .addOnSuccessListener {
            // Enrollment complete.
        }
    

Nutzer mit einem zweiten Faktor anmelden

Verwenden Sie den folgenden Code, um Nutzer mit der TOTP-MFA anzumelden:

  1. Rufen Sie eine der signInWith-Methoden auf, so als würden Sie keine MFA verwenden. Beispiel: signInWithEmailAndPassword(). Wenn die Methode eine FirebaseAuthMultiFactorException auslöst, starten Sie den MFA-Ablauf Ihrer App.

    Firebase.auth.signInWithEmailAndPassword(email, password)
        .addOnSuccessListener { result ->
            // If the user is not enrolled with a second factor and provided valid
            // credentials, sign-in succeeds.
    
            // (If your app requires MFA, this could be considered an error
            // condition, which you would resolve by forcing the user to enroll a
            // second factor.)
    
            // ...
        }
        .addOnFailureListener { exception ->
            when (exception) {
                is FirebaseAuthMultiFactorException -> {
                    // Initiate your second factor sign-in flow. (See next step.)
                    // ...
                }
            }
        }
    
  2. Im MFA-Ablauf Ihrer App sollte der Nutzer zuerst aufgefordert werden, den zweiten Faktor auszuwählen, den er verwenden möchte. Eine Liste der unterstützten zweiten Faktoren finden Sie in der Eigenschaft hints einer MultiFactorResolver-Instanz:

    val enrolledFactors = exception.resolver.hints.map { it.displayName }
    
  3. Wenn der Nutzer TOTP verwenden möchte, fordern Sie ihn auf, das in seiner Authenticator App angezeigte TOTP einzugeben und sich damit anzumelden:

    when (exception.resolver.hints[selectedIndex].factorId) {
        TotpMultiFactorGenerator.FACTOR_ID -> {
            val otpFromAuthenticator = // OTP typed by the user.
            val assertion = TotpMultiFactorGenerator.getAssertionForSignIn(
                exception.resolver.hints[selectedIndex].uid,
                otpFromAuthenticator
            )
            exception.resolver.resolveSignIn(assertion)
                .addOnSuccessListener { result ->
                    // Successfully signed in!
                }
                .addOnFailureListener { resolveError ->
                    // Invalid or expired OTP.
                }
        }
        PhoneMultiFactorGenerator.FACTOR_ID -> {
            // Handle SMS second factor.
        }
    }
    

Von der TOTP-MFA abmelden

In diesem Abschnitt wird beschrieben, wie Sie die Abmeldung eines Nutzers von der TOTP-MFA verarbeiten.

Wenn ein Nutzer sich für mehrere MFA-Optionen registriert hat und sich von der zuletzt aktivierten Option abmeldet, erhält er eine auth/user-token-expired-Meldung und wird abgemeldet. Der Nutzer muss sich noch einmal anmelden und seine vorhandenen Anmeldedaten bestätigen, z. B. eine E-Mail-Adresse und ein Passwort.

Verwenden Sie den folgenden Code, um den Nutzer abzumelden, den Fehler zu verarbeiten und die erneute Authentifizierung auszulösen:

Firebase.auth.currentUser.multiFactor.unenroll(mfaEnrollmentId)
    .addOnSuccessListener {
        // Second factor unenrolled.
    }
    .addOnFailureListener { exception ->
        when (exception) {
            is FirebaseAuthInvalidUserException -> {
                // Second factor unenrolled. If the user was signed out, re-authenticate
                // them.

                // For example, if they signed in with a password, prompt them to
                // provide it again, then call `reauthenticateWithCredential()` as shown
                // below.
                val credential = EmailAuthProvider.getCredential(email, password)
                currentUser.reauthenticate(credential)
                    .addOnSuccessListener { 
                        // Success!
                    }
                    .addOnFailureListener { 
                        // Bad email address and password combination.
                    }
            }
        }
    }

Nächste Schritte