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

Wenn Sie auf Firebase Authentication with Identity Platform umgestellt haben, können Sie Ihrer App die Multi-Faktor-Authentifizierung (MFA) mit einem zeitbasierten Einmalpasswort (TOTP) hinzufügen.

Mit Firebase Authentication with Identity Platform können Sie ein TOTP als zusätzlichen Faktor für die MFA verwenden. Wenn Sie diese Funktion aktivieren, sehen Nutzer, die sich bei Ihrer Anwendung anmelden möchten, eine Anfrage für ein TOTP. Dazu muss er eine Authentifizierungs-App verwenden, die gültige TOTP-Codes generieren kann, z. B. Google Authenticator.

Hinweis

  1. Aktivieren Sie mindestens einen Anbieter, der MFA unterstützt. Hinweis: MFA wird von allen Anbietern außer den folgenden unterstützt:

    • Telefonauthentifizierung
    • Anonyme Authentifizierung
    • Benutzerdefinierte Auth-Tokens
    • Apple Game Center
  2. Achten Sie darauf, dass die Anwendung die E-Mail-Adressen der Nutzer überprüft. Die Multi-Faktor-Authentifizierung 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 echten Inhaber sperren, indem sie einen zweiten Faktor hinzufügen.

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

    TOTP-MFA wird nur unter Apple SDK-Version 10.12.0 und höher und nur unter iOS unterstützt.

TOTP-MFA aktivieren

Wenn Sie TOTP als zweiten Faktor aktivieren möchten, verwenden Sie Admin SDK oder rufen Sie den REST-Endpunkt der Projektkonfiguration auf.

So verwenden Sie Admin SDK:

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

    TOTP MFA wird nur ab der Firebase Admin Node.js SDK-Version 11.6.0 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 benachbarten Zeitfensterintervalle, in denen TOTPs akzeptiert werden sollen, von null bis zehn. Der Standardwert ist 5.

      Bei TOTPs wird sichergestellt, dass zwei Parteien (der Server und der Validator) OTPs innerhalb desselben Zeitraums (in der Regel 30 Sekunden) generieren, dass sie dasselbe Passwort generieren. Um jedoch Abweichungen zwischen den Uhren der Parteien und der Reaktionszeit von Menschen zu berücksichtigen, können Sie den TOTP-Dienst so konfigurieren, dass auch TOTPs aus benachbarten Zeitfenstern akzeptiert werden.

So aktivieren Sie die TOTP-Mehrfachauthentifizierung mit der REST API:

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 sorgen dafür, dass zwei Parteien (der Prüfer und der Validator) innerhalb desselben Zeitfensters (in der Regel 30 Sekunden lang) dasselbe Passwort generieren. Um jedoch Abweichungen zwischen den Uhren der Parteien und der Reaktionszeit von Menschen zu berücksichtigen, können Sie den TOTP-Dienst so konfigurieren, dass auch TOTPs aus benachbarten Zeitfenstern akzeptiert werden.

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 Anwendung zwar fördern, aber nicht verlangen 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 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.
    guard let mfaSession = try? await currentUser.multiFactor.session() else { return }
    guard let totpSecret = try? await TOTPMultiFactorGenerator.generateSecret(with: mfaSession) else { return }
    
    // 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 Geheimnis an und bitten Sie ihn, es in seiner Authenticator-App einzugeben:

    // Display this key:
    let secret = totpSecret.sharedSecretKey()
    

    Sie können den geheimen Schlüssel nicht nur anzeigen, sondern auch versuchen, ihn automatisch der Standard-Authentifizierungs-App des Geräts hinzuzufügen. Generieren Sie dazu einen mit Google Authenticator kompatiblen Schlüssel-URI und übergeben Sie ihn an openInOTPApp(withQRCodeURL:):

    let otpAuthUri = totpSecret.generateQRCodeURL(
        withAccountName: currentUser.email ?? "default account",
        issuer: "Your App Name")
    totpSecret.openInOTPApp(withQRCodeURL: otpAuthUri)
    

    Nachdem der Nutzer sein Geheimnis seiner Authentifizierungs-App hinzugefügt hat, werden TOTPs generiert.

  4. Bitten Sie den Nutzer, das von der Authentifizierungs-App angezeigte TOTP einzugeben und die MFA-Registrierung damit abzuschließen:

    // Ask the user for a verification code from the authenticator app.
    let verificationCode = // Code from user input.
    
    // Finalize the enrollment.
    let multiFactorAssertion = TOTPMultiFactorGenerator.assertionForEnrollment(
        with: totpSecret,
        oneTimePassword: verificationCode)
    do {
        try await currentUser.multiFactor.enroll(
            with: multiFactorAssertion,
            displayName: "TOTP")
    } catch {
        // Wrong or expired OTP. Re-prompt the user.
    }
    

Nutzer mit einem zweiten Faktor anmelden

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

  1. Rufen Sie eine der signIn(with...:)-Methoden auf, als würden Sie keine MFA verwenden (z. B. signIn(withEmail:password:)). Wenn die Methode einen Fehler mit dem Code secondFactorRequired zurückgibt, starten Sie den MFA-Ablauf Ihrer App.

    do {
        let authResult = try await Auth.auth().signIn(withEmail: email, password: password)
    
        // 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.)
    
        // ...
    } catch let error as AuthErrorCode where error.code == .secondFactorRequired {
        // Initiate your second factor sign-in flow. (See next step.)
        // ...
    } catch {
        // Other auth error.
        throw error
    }
    
  2. Der MFA-Ablauf Ihrer App sollte den Nutzer zuerst auffordern, den gewünschten zweiten Faktor auszuwählen. Eine Liste der unterstützten zweiten Faktoren finden Sie in der hints-Eigenschaft einer MultiFactorResolver-Instanz:

    let mfaKey = AuthErrorUserInfoMultiFactorResolverKey
    guard let resolver = error.userInfo[mfaKey] as? MultiFactorResolver else { return }
    let enrolledFactors = resolver.hints.map(\.displayName)
    
  3. Wenn der Nutzer TOTP verwenden möchte, bitte ihn, den in seiner Authenticator App angezeigten TOTP-Code einzugeben und sich damit anzumelden:

    let multiFactorInfo = resolver.hints[selectedIndex]
    switch multiFactorInfo.factorID {
    case TOTPMultiFactorID:
        let otpFromAuthenticator = // OTP typed by the user.
        let assertion = TOTPMultiFactorGenerator.assertionForSignIn(
            withEnrollmentID: multiFactorInfo.uid,
            oneTimePassword: otpFromAuthenticator)
        do {
            let authResult = try await resolver.resolveSignIn(with: assertion)
        } catch {
            // Wrong or expired OTP. Re-prompt the user.
        }
    default:
        return
    }
    

Von TOTP MFA abmelden

In diesem Abschnitt wird beschrieben, wie Sie mit einem Nutzer umgehen, der sich von TOTP MFA abmeldet.

Wenn sich ein Nutzer für mehrere MFA-Optionen registriert hat und die Registrierung für die zuletzt aktivierte Option aufhebt, erhält er eine auth/user-token-expired 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.

Verwende den folgenden Code, um die Registrierung des Nutzers aufzuheben, den Fehler zu behandeln und die erneute Authentifizierung auszulösen:

guard let currentUser = Auth.auth().currentUser else { return }

// Prompt the user to select a factor to unenroll, from this array:
currentUser.multiFactor.enrolledFactors

// ...

// Unenroll the second factor.
let multiFactorInfo = currentUser.multiFactor.enrolledFactors[selectedIndex]
do {
    try await currentUser.multiFactor.unenroll(with: multiFactorInfo)
} catch let error as AuthErrorCode where error.code == .invalidUserToken {
    // Second factor unenrolled, but the user was signed out. Re-authenticate
    // them.
}

Nächste Schritte