Wie sich eine eigene TOTP-basierte 2FA-Lösung für den Customer-Login implementieren lässt, weil Magentos natives 2FA-Modul nur den Admin-Bereich abdeckt
Magento 2 bringt seit einigen Versionen ein solides, natives Zwei-Faktor-Modul mit, doch dieses schützt ausschließlich den Admin-Bereich. Für Kundenkonten existiert keine vergleichbare eingebaute Lösung, obwohl gerade Shops mit gespeicherten Zahlungsdaten, Guthabenkonten oder sensiblen B2B-Bestelldaten ein legitimes Interesse an einer zusätzlichen Absicherung des Storefront-Logins haben. Dieser Artikel zeigt, wie sich eine eigene TOTP-basierte Zwei-Faktor-Authentifizierung für Kundenkonten sauber in den bestehenden Authentifizierungs-Flow einhängen lässt, inklusive der UX-Abwägung zwischen Pflicht und Opt-in sowie einem durchdachten Recovery-Code-Konzept.
Inhaltsverzeichnis
- 1. Warum Magentos natives 2FA-Modul nur den Admin-Bereich abdeckt
- 2. Architektur einer eigenen Customer-2FA-Lösung
- 3. TOTP-Verifizierung implementieren
- 4. UX-Abwägung: 2FA verpflichtend oder optional anbieten
- 5. Onboarding-Flow: 2FA-Aktivierung Schritt für Schritt
- 6. Recovery-Codes: Zugriff ohne verlorenes Gerät sicherstellen
- 7. Session-Handling und Remember-Device-Funktion
- 8. Admin-Übersicht für den Kundenservice
- 9. Customer-2FA-Implementierungsschritte im Überblick
- 10. Zusammenfassung
- 11. FAQ
1. Warum Magentos natives 2FA-Modul nur den Admin-Bereich abdeckt
Das Modul Magento_TwoFactorAuth wurde ursprünglich als Reaktion auf gehäufte Admin-Account-Übernahmen eingeführt und ist konsequent auf den Backend-Login zugeschnitten: Es hängt sich in den Admin-Authentifizierungs-Flow ein, verwaltet Provider wie Google Authenticator oder Duo Security und bietet eine eigene Admin-UI zur Verwaltung der aktivierten Faktoren. Der gesamte Aufbau des Moduls, von der Datenbanktabelle bis zu den Controllern, ist strikt auf den adminhtml-Bereich beschränkt.
Für den Customer-Bereich gibt es architektonisch keine Entsprechung, weil Magentos Kernteam den Storefront-Login historisch als geringeres Risiko eingestuft hat als den Admin-Zugang, der potenziell Zugriff auf den gesamten Shop erlaubt. Diese Einschätzung trifft aber nicht mehr automatisch zu, sobald Kundenkonten selbst wertvolle Daten enthalten, etwa gespeicherte Zahlungsmethoden, Bestellhistorien mit Adressdaten oder im B2B-Kontext Zugriff auf firmenweite Preislisten und Bestellfreigaben. Gerade bei Konten mit hinterlegter Kreditkarte oder gespeichertem Guthaben ist ein reines Passwort als einziger Schutzwall oft nicht mehr zeitgemäß, unabhängig davon, was der Kernteam ursprünglich als angemessenes Risiko eingestuft hat. Credential-Stuffing-Angriffe mit Datensätzen aus fremden Datenlecks treffen dabei gerade Kundenkonten mit wiederverwendeten Passwörtern besonders häufig, weit häufiger als gezielte Angriffe auf einzelne Admin-Zugänge.
2. Architektur einer eigenen Customer-2FA-Lösung
Der saubere Einstiegspunkt ist ein Plugin auf Magento\Customer\Model\AccountManagement::authenticate(), das nach erfolgreicher Passwort-Prüfung greift, aber vor der eigentlichen Session-Etablierung. Statt den Kunden sofort einzuloggen, wird bei aktivierter 2FA zunächst ein temporärer, zeitlich begrenzter Zwischenzustand gesetzt, der signalisiert, dass Passwort korrekt war, der zweite Faktor aber noch aussteht.
Das TOTP-Secret selbst gehört nicht in die customer_entity-Tabelle, sondern in eine eigene Tabelle mit Fremdschlüssel auf die Customer-ID, verschlüsselt über Magentos EncryptorInterface gespeichert. Diese Trennung verhindert, dass ein Datenbank-Dump der Standardtabellen versehentlich die 2FA-Secrets im Klartext offenlegt, und erlaubt eine unabhängige Zugriffssteuerung auf die sicherheitskritischen Daten.
<!-- app/code/Mironsoft/CustomerTwoFactor/etc/db_schema.xml -->
<table name="mironsoft_customer_totp_secret" resource="default" engine="innodb">
<column xsi:type="int" name="customer_id" unsigned="true" nullable="false"/>
<column xsi:type="text" name="secret_encrypted" nullable="false"/>
<column xsi:type="smallint" name="is_enabled" unsigned="true" nullable="false" default="0"/>
<column xsi:type="timestamp" name="confirmed_at" nullable="true"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="customer_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="MIRONSOFT_TOTP_CUSTOMER_ID"
table="mironsoft_customer_totp_secret" column="customer_id"
referenceTable="customer_entity" referenceColumn="entity_id" onDelete="CASCADE"/>
</table>
3. TOTP-Verifizierung implementieren
TOTP, Time-based One-Time Password, generiert aus einem geteilten Secret und der aktuellen Uhrzeit einen sechsstelligen Code, der typischerweise alle dreißig Sekunden wechselt. Auf Serverseite berechnet Magento denselben Code aus dem gespeicherten Secret und vergleicht ihn mit der Nutzereingabe, wobei ein kleines Zeitfenster von einem Schritt vor und zurück toleriert werden sollte, um Uhrzeitabweichungen zwischen Server und Authenticator-App abzufedern.
Die eigentliche TOTP-Berechnung sollte nicht selbst implementiert, sondern über eine geprüfte Bibliothek eingebunden werden, da subtile Fehler bei der Base32-Dekodierung des Secrets oder der HMAC-Berechnung die gesamte Sicherheit des Verfahrens untergraben können. Der Zwischenzustand aus dem Authentifizierungs-Plugin wird erst nach erfolgreicher Code-Verifikation in eine vollwertige Kundensession überführt.
<?php
declare(strict_types=1);
namespace Mironsoft\CustomerTwoFactor\Model;
/**
* Verifiziert einen vom Kunden eingegebenen TOTP-Code gegen das gespeicherte Secret.
*/
final class TotpVerifier
{
private const TIME_STEP_SECONDS = 30;
private const ALLOWED_DRIFT_STEPS = 1;
/**
* Prüft, ob der eingegebene Code innerhalb des Toleranzfensters gültig ist.
*
* @param string $secret Base32-kodiertes TOTP-Secret
* @param string $code Vom Kunden eingegebener sechsstelliger Code
* @return bool
*/
public function verify(string $secret, string $code): bool
{
$currentStep = (int) floor(time() / self::TIME_STEP_SECONDS);
for ($drift = -self::ALLOWED_DRIFT_STEPS; $drift <= self::ALLOWED_DRIFT_STEPS; $drift++) {
if (hash_equals($this->generateCode($secret, $currentStep + $drift), $code)) {
return true;
}
}
return false;
}
}
4. UX-Abwägung: 2FA verpflichtend oder optional anbieten
Eine verpflichtende 2FA für alle Kundenkonten erhöht die Sicherheit spürbar, erzeugt aber messbar höhere Absprungraten beim Login und zusätzlichen Support-Aufwand für Kunden, die ihr Smartphone verloren haben oder die Authenticator-App neu einrichten müssen. Für einen klassischen B2C-Shop mit geringem Warenkorbwert ist ein verpflichtender zweiter Faktor bei jedem Login oft unverhältnismäßig zur eigentlichen Risikolage.
Ein bewährter Mittelweg ist ein risikobasierter, opt-in-orientierter Ansatz: 2FA wird als optionale, aber sichtbar beworbene Einstellung im Kundenkonto angeboten, während sie für bestimmte Kontexte verpflichtend wird, etwa vor dem Ändern der Lieferadresse einer laufenden Bestellung, vor dem Hinzufügen einer neuen Zahlungsmethode oder generell für B2B-Firmenkonten mit Bestellfreigabe-Berechtigung. Diese kontextabhängige Pflicht lässt sich über dieselbe Plugin-Architektur an gezielten Stellen im Checkout und in der Kontoverwaltung einhängen, statt sie pauschal an den Login zu koppeln.
5. Onboarding-Flow: 2FA-Aktivierung Schritt für Schritt
Der Aktivierungsvorgang beginnt üblicherweise mit der serverseitigen Generierung eines neuen TOTP-Secrets, das als QR-Code dargestellt wird, damit der Kunde es bequem mit seiner Authenticator-App scannen kann. Wichtig ist, das Secret zu diesem Zeitpunkt noch nicht als aktiv zu markieren, sondern zunächst nur temporär vorzuhalten, da der Kunde die App möglicherweise noch nicht erfolgreich eingerichtet hat.
Erst wenn der Kunde im zweiten Schritt einen aktuell gültigen sechsstelligen Code aus seiner frisch eingerichteten App korrekt eingibt, wird das Secret endgültig als aktiv markiert und die Recovery-Codes einmalig angezeigt. Dieser Bestätigungsschritt verhindert, dass sich ein Kunde versehentlich mit einem falsch gescannten oder nicht funktionierenden Secret aussperrt, weil ein funktionierender Roundtrip nachgewiesen sein muss, bevor 2FA für künftige Logins tatsächlich verpflichtend wird.
6. Recovery-Codes: Zugriff ohne verlorenes Gerät sicherstellen
Ohne einen Wiederherstellungsweg sperrt sich ein Kunde bei Verlust des Smartphones faktisch selbst aus seinem Konto aus, was unweigerlich zu Support-Tickets führt. Der Standardansatz sind Recovery-Codes: eine feste Anzahl einmalig verwendbarer Codes, die bei der Aktivierung von 2FA einmalig angezeigt und zum Ausdrucken oder sicheren Speichern angeboten werden.
Jeder Recovery-Code darf technisch nur einmal funktionieren und muss nach Verwendung sofort als verbraucht markiert werden, gespeichert als Hash und nicht im Klartext, analog zum Passwort selbst. Fällt die Anzahl verbleibender Codes unter einen Schwellenwert, etwa zwei von ursprünglich zehn, sollte der Kunde beim nächsten erfolgreichen Login proaktiv zur Generierung eines neuen Satzes aufgefordert werden, damit er nicht unbemerkt vollständig ohne Fallback dasteht.
7. Session-Handling und Remember-Device-Funktion
Ein zweiter Faktor bei absolut jedem Login erhöht die Sicherheit, nervt aber bei häufig genutzten, vertrauenswürdigen Geräten spürbar. Eine Remember-Device-Funktion speichert nach erfolgreicher 2FA-Verifikation ein signiertes, zeitlich begrenztes Token im Browser des Kunden, das bei künftigen Logins von demselben Gerät den zweiten Faktor für einen definierten Zeitraum, üblicherweise dreißig Tage, überspringt.
Dieses Token darf niemals das Passwort ersetzen, sondern ausschließlich die 2FA-Abfrage überspringen, und sollte an Gerätemerkmale wie User-Agent gebunden sowie serverseitig widerrufbar sein, etwa wenn der Kunde in seinen Kontoeinstellungen alle aktiven Sitzungen abmeldet. Ohne diese Widerrufsmöglichkeit bliebe ein gestohlenes Remember-Device-Token dauerhaft gültig, selbst nachdem der Kunde sein Passwort geändert hat.
8. Admin-Übersicht für den Kundenservice
Damit der Support Kunden bei verlorenem Gerät und aufgebrauchten Recovery-Codes helfen kann, braucht es eine eigene Admin-Grid-Ansicht mit dem 2FA-Status pro Kundenkonto sowie einer Aktion zum kontrollierten Zurücksetzen der 2FA-Konfiguration nach Identitätsprüfung des Kunden über den regulären Support-Kanal. Diese Ansicht sollte zusätzlich anzeigen, wann die 2FA aktiviert wurde und wie viele Recovery-Codes noch übrig sind, damit der Support-Mitarbeiter die Situation ohne Rückfrage beim Entwicklerteam einschätzen kann.
Dieser Reset-Vorgang muss zwingend protokolliert werden, inklusive des Admin-Nutzers, der ihn ausgelöst hat, weil ein Zurücksetzen der 2FA faktisch eine zweite, eigenständige Authentifizierungs-Schwachstelle schafft, falls ein Angreifer den Support-Prozess selbst zu manipulieren versucht, etwa durch Social Engineering. Ein zusätzlicher Zeitverzug zwischen Reset-Anfrage und tatsächlicher Ausführung, etwa eine Bestätigung per registrierter E-Mail-Adresse, verringert dieses Risiko weiter, ohne den legitimen Kunden übermäßig zu belasten.
9. Customer-2FA-Implementierungsschritte im Überblick
Die folgende Tabelle fasst die zentralen Bausteine einer eigenen Customer-2FA-Lösung mit ihrer jeweiligen Rolle zusammen.
| Baustein | Zuständige Komponente | Rolle | Sicherheitsaspekt |
|---|---|---|---|
| Login-Zwischenzustand | Plugin auf AccountManagement::authenticate | Session erst nach zweitem Faktor etablieren | Verhindert vollständigen Login nur mit Passwort |
| TOTP-Secret-Speicherung | Eigene Tabelle mit EncryptorInterface | Verschlüsselte Ablage getrennt von customer_entity | Kein Klartext-Secret bei Datenbank-Dump |
| Code-Verifikation | TotpVerifier mit Zeitfenster-Toleranz | Sechsstelligen Code gegen Secret prüfen | Bewährte Bibliothek statt Eigenimplementierung |
| Recovery-Codes | Gehashte Einmal-Codes | Zugriff bei Geräteverlust sicherstellen | Jeder Code nur einmal verwendbar |
| Remember-Device-Token | Signiertes, widerrufbares Token | 2FA-Abfrage bei vertrauenswürdigen Geräten überspringen | Serverseitig widerrufbar bei Passwortänderung |
Mironsoft
Magento-Entwicklung, Modul-Beratung und Systemarchitektur
Magento-Projekt, das eine zweite Meinung oder erfahrene Umsetzung braucht?
Wir entwickeln individuelle Magento-Module, beraten bei Architekturentscheidungen und übernehmen komplexe Umsetzungen, von der Service-Contract-Planung bis zum produktionsreifen Deployment.
Architektur-Beratung
Modul- und Systemarchitektur vor der Umsetzung fundiert durchdenken lassen.
Custom-Modul-Entwicklung
Individuelle Magento-Module nach Best Practices sauber umsetzen.
Code-Review & Audit
Bestehende Module auf Performance, Sicherheit und Wartbarkeit prüfen lassen.
10. Zusammenfassung
Kunden-2FA: Das Wichtigste auf einen Blick
Kernidee
Magentos natives 2FA-Modul deckt nur den Admin ab, Customer-2FA braucht eine eigene, saubere Implementierung.
Zentraler Einstiegspunkt
Ein Plugin auf AccountManagement::authenticate vor der eigentlichen Session-Etablierung.
Größtes UX-Risiko
Verpflichtende 2FA bei jedem Login ohne Remember-Device-Funktion erhöht die Login-Absprungrate spürbar.
Erfolgskriterium
Recovery-Codes und ein protokollierter Support-Reset verhindern dauerhafte Aussperrung ohne neue Angriffsfläche.