Fügen Sie Ihrer Android-App die TOTP-Multi-Faktor-Authentifizierung hinzu

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

Mit der Firebase-Authentifizierung mit Identity Platform können Sie ein TOTP als zusätzlichen Faktor für MFA verwenden. Wenn Sie diese Funktion aktivieren, wird Benutzern, die versuchen, sich bei Ihrer App anzumelden, eine TOTP-Anfrage angezeigt. Um es zu generieren, müssen sie eine Authentifizierungs-App verwenden, die in der Lage ist, gültige TOTP-Codes zu generieren, wie z. B. Google Authenticator .

Bevor Sie beginnen

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

    • Telefonauthentifizierung
    • Anonyme Auth
    • Benutzerdefinierte Authentifizierungstoken
    • Apple Game Center
  2. Stellen Sie sicher, dass Ihre App die E-Mail-Adressen der Benutzer überprüft. MFA erfordert eine E-Mail-Bestätigung. Dies verhindert, dass sich böswillige Akteure mit einer E-Mail-Adresse, die ihnen nicht gehört, für einen Dienst registrieren und dann den tatsächlichen Eigentümer der E-Mail-Adresse durch Hinzufügen eines zweiten Faktors ausschließen.

  3. Falls Sie dies noch nicht getan haben, installieren Sie das Firebase Android SDK .

    TOTP MFA wird nur auf der Android SDK-Version v22.1.0 und höher unterstützt.

Aktivieren Sie TOTP MFA

Um TOTP als zweiten Faktor zu aktivieren, verwenden Sie das Admin SDK oder rufen Sie den REST-Endpunkt der Projektkonfiguration auf.

Gehen Sie wie folgt vor, um das Admin SDK zu verwenden:

  1. Falls Sie dies noch nicht getan haben, installieren Sie das Firebase Admin Node.js SDK .

    TOTP MFA wird nur auf Firebase Admin Node.js SDK-Versionen 11.6.0 und höher unterstützt.

  2. Führen Sie Folgendes 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 benachbarter Zeitfensterintervalle, aus denen TOTPs akzeptiert werden sollen, von null bis zehn. Der Standardwert ist fünf.

      TOTPs funktionieren, indem sie sicherstellen, dass zwei Parteien (der Prüfer und der Validator), die OTPs innerhalb desselben Zeitfensters (normalerweise 30 Sekunden lang) generieren, dasselbe Passwort generieren. Um jedoch der Taktabweichung zwischen Parteien und der menschlichen Reaktionszeit Rechnung zu tragen, können Sie den TOTP-Dienst so konfigurieren, dass er auch TOTPs von benachbarten Fenstern akzeptiert.

Führen Sie Folgendes aus, um TOTP MFA mithilfe der 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 von null bis zehn. Der Standardwert ist fünf.

    TOTPs funktionieren, indem sie sicherstellen, dass zwei Parteien (der Prüfer und der Validator), die OTPs innerhalb desselben Zeitfensters (normalerweise 30 Sekunden lang) generieren, dasselbe Passwort generieren. Um jedoch der Taktabweichung zwischen Parteien und der menschlichen Reaktionszeit Rechnung zu tragen, können Sie den TOTP-Dienst so konfigurieren, dass er auch TOTPs von benachbarten Fenstern akzeptiert.

Wählen Sie ein Anmeldemuster

Sie können wählen, ob Ihre App eine Multi-Faktor-Authentifizierung erfordert und wie und wann Sie Ihre Benutzer registrieren. Zu den häufigsten Mustern gehören die folgenden:

  • Registrieren Sie den zweiten Faktor des Benutzers im Rahmen der Registrierung. Verwenden Sie diese Methode, wenn Ihre App eine mehrstufige Authentifizierung für alle Benutzer erfordert.

  • Bieten Sie bei der Registrierung eine überspringbare Option zur Registrierung eines zweiten Faktors an. Wenn Sie die Multi-Faktor-Authentifizierung in Ihrer App fördern, aber nicht fordern möchten, können Sie diesen Ansatz verwenden.

  • Bieten Sie die Möglichkeit, einen zweiten Faktor über die Konto- oder Profilverwaltungsseite des Benutzers anstelle des Anmeldebildschirms hinzuzufügen. Dies minimiert die Reibung während des Registrierungsprozesses und stellt gleichzeitig die Multi-Faktor-Authentifizierung für sicherheitsempfindliche Benutzer zur Verfügung.

  • Erfordern Sie das schrittweise Hinzufügen eines zweiten Faktors, wenn der Benutzer auf Funktionen mit erhöhten Sicherheitsanforderungen zugreifen möchte.

Registrieren Sie Benutzer bei TOTP MFA

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

  1. Authentifizieren Sie den Benutzer erneut.

  2. Generieren Sie ein TOTP-Geheimnis für den authentifizierten Benutzer:

    // 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 Benutzer das Geheimnis an und fordern Sie ihn auf, es in seine Authentifizierungs-App einzugeben:

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

    Zusätzlich zur Anzeige des geheimen Schlüssels können Sie versuchen, ihn automatisch zur Standard-Authentifizierungs-App des Geräts hinzuzufügen. Generieren Sie dazu einen 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 Benutzer sein Geheimnis zu seiner Authentifizierungs-App hinzugefügt hat, beginnt diese mit der Generierung von TOTPs.

  4. Fordern Sie den Benutzer auf, das von seiner Authentifizierungs-App angezeigte TOTP einzugeben und es zum Abschließen der MFA-Registrierung zu verwenden:

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

Melden Sie Benutzer mit einem zweiten Faktor an

Um Benutzer mit TOTP MFA anzumelden, verwenden Sie den folgenden Code:

  1. Rufen Sie eine der signInWith -Methoden auf, als würden Sie MFA nicht verwenden. (Zum Beispiel signInWithEmailAndPassword() .) Wenn die Methode eine FirebaseAuthMultiFactorException auslöst, starten Sie den MFA-Flow 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. Der MFA-Ablauf Ihrer App sollte den Benutzer zunächst dazu auffordern, den zweiten Faktor auszuwählen, den er verwenden möchte. Sie können eine Liste der unterstützten zweiten Faktoren erhalten, indem Sie die hints Eigenschaft einer MultiFactorResolver Instanz untersuchen:

    val enrolledFactors = exception.resolver.hints.map { it.displayName }
    
  3. Wenn sich der Benutzer für die Verwendung von TOTP entscheidet, fordern Sie ihn auf, das in seiner Authentifizierungs-App angezeigte TOTP einzugeben und es zum Anmelden zu verwenden:

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

Melden Sie sich von TOTP MFA ab

In diesem Abschnitt wird beschrieben, wie mit der Abmeldung eines Benutzers von TOTP MFA umgegangen wird.

Wenn sich ein Benutzer für mehrere MFA-Optionen angemeldet hat und sich von der zuletzt aktivierten Option abmeldet, erhält er ein auth/user-token-expired und wird abgemeldet. Der Benutzer muss sich erneut anmelden und seine vorhandenen Anmeldeinformationen überprüfen, beispielsweise eine E-Mail-Adresse und ein Kennwort.

Um den Benutzer abzumelden, den Fehler zu behandeln und eine erneute Authentifizierung auszulösen, verwenden Sie den folgenden Code:

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

Was kommt als nächstes