
# Einen Anmeldeschritt ausführen

`POST /fapi/v1/transactions/current/steps/{step}` · wird vom Anmeldehost der Umgebung aufgerufen

Führt einen Schritt der aktuellen Transaktion aus. Diese Version akzeptiert die Schritte `identifier` und `password`. Jeder fehlgeschlagene
Nachweisschritt liefert dieselbe `401 invalid_credentials`, sodass die Antwort nie verrät, ob ein Konto existiert. Wenn
der Passwortschritt die Transaktion abschließt, werden die Sitzungs-Cookies `__Host-idp_session` (und bei Bedarf
`__Host-idp_device`) gesetzt und das Transaktions-Cookie wird entfernt.

## Anfrage

Header:

| Header | Erforderlich | Beschreibung |
| --- | --- | --- |
| `Idp-Client` | ja | Kennung des SDK. |
| `Origin` | ja | Muss genau `https://<sign-in host>` sein. |
| `Idp-Csrf-Token` | ja | Das `csrf_token` aus dem Transaktionsobjekt. |

Pfad: `step`, der Name des Schritts (`identifier`, `password`, `sso_start`).

Beim Schritt `otp_send` listet `next_steps[].methods` die passwortlosen Methoden auf, die die wirksame Richtlinie erlaubt (`email_otp`, `magic_link`); ein Client bietet nur diese an.

Body (die Felder hängen vom Schritt ab; `next_steps[].fields` listet sie auf):

| Feld | Typ | Beschreibung |
| --- | --- | --- |
| `identifier` | string | E-Mail-Adresse, Telefonnummer oder Benutzername (Schritt `identifier`), maximal 320 Zeichen. |
| `password` | string | Das Passwort (Schritt `password`), maximal 128 Zeichen. |
| `connection_id` | string | Ein `sso_connections[].connection_id`-Wert (Schritt `sso_start`). |

## Antwort

`200 OK` mit der Transaktion nach dem Schritt. Eine `completed`-Transaktion hat kein `csrf_token`.

Wenn die Umgebung einen zweiten Faktor verlangt und der Benutzer noch keinen hat, kann sich ein Benutzer, der sich noch innerhalb der
`mfa.enrollment_grace_days` der Umgebung befindet, trotzdem anmelden. Die Antwort `completed` enthält dann `mfa_enrollment`:
`required_by` (RFC 3339, das vom Server berechnete Ende der Frist) und `methods` (`webauthn`, `totp`: die Faktoren, die der
Benutzer jetzt einrichten kann, in Bildschirmreihenfolge). Zeigen Sie das Datum an und lassen Sie den Benutzer fortfahren; die Einrichtung erfolgt in den
Kontoeinstellungen. Das Feld fehlt, wenn keine Frist gilt, der Benutzer die Richtlinie bereits erfüllt oder die Einrichtung sofort erforderlich ist. Das `min_acr` einer Anwendung und das angeforderte `acr_values` werden durch die Frist nie aufgeschoben.

## Enterprise-SSO (Ermittlung des Heimat-Realms)

Wenn der Schritt `identifier` eine E-Mail-Adresse erhält, deren Domain zu einer Enterprise-Verbindung gehört, wird die Anmeldung
über diese Verbindung fortgesetzt. Für die Ermittlung wird nur der Teil nach `@` verwendet.

- Eine Verbindung: Die Transaktion wechselt zu `federated_redirect`, und die Antwort enthält `redirect_url`, die
  Startadresse des Identitätsanbieters. Navigieren Sie das oberste Fenster dorthin. Die Adresse enthält ein einmaliges Token: Speichern oder protokollieren Sie es nicht.
- Mehrere Verbindungen: Die Transaktion bleibt in `identifier_pending`, und die Antwort listet `sso_connections`
  auf (`connection_id`, `display_name`, `protocol`). Zeigen Sie `display_name` als Text an und senden Sie die Auswahl des Benutzers mit dem
  Schritt `sso_start` (`identifier` und `connection_id`). Eine Verbindung, die für die Domain nicht angeboten wird, liefert
  `422 validation_failed`.
- Keine Verbindung oder die Ermittlung ist vorübergehend nicht verfügbar: Die normale Anmeldung wird fortgesetzt, sodass ein Ausfall die anderen Anmeldemethoden nie blockiert. `sso_start` ist eine ausdrückliche Wahl und liefert stattdessen `503 temporarily_unavailable`.

Wenn die Anmeldeanfrage eine Organisation nennt, die SSO verlangt, bietet die Transaktion nur die Verbindungen dieser Organisation an: Der Passwort- und der E-Mail-Code-Schritt werden nicht angeboten, und der Passkey bleibt nur verfügbar, wenn die
Organisation Notfallkonten (Break-Glass) hat. Beim Erstellen der Transaktion wird die einzige Verbindung bereits gestartet
(`federated_redirect` mit `redirect_url`), oder mehrere werden in `sso_connections` aufgelistet. Senden Sie die Auswahl nur mit `sso_start`
und `connection_id`; `identifier` ist hier optional. Unter dieser Vorgabe weicht die Ermittlung nicht auf andere Methoden aus: Wenn die Enterprise-Anmeldung nicht erreicht werden kann, liefert der Schritt `503 temporarily_unavailable`. Dasselbe gilt, wenn die E-Mail-Domain zu einer Organisation gehört, die SSO für ihre verifizierten Domains verlangt.

Nach dem Identitätsanbieter kehrt der Browser zu `/u/sso/complete` auf dem Anmeldehost zurück; die gehostete Seite schließt die Anmeldung ab.

## Enterprise-Anmeldung mit einem bestehenden Konto verknüpfen

Wenn eine Enterprise-Verbindung E-Mail-Adressen nicht bestätigt und die von ihr übermittelte Adresse bereits auf einem Konto der Umgebung verifiziert ist, öffnet die Enterprise-Anmeldung keine Sitzung. Der Browser kehrt mit einer neuen Transaktion zur gehosteten Anmeldeseite zurück, deren Objekt `account_link` enthält: `connection_name` und, wenn die Verbindung zu einer Organisation gehört, `organization_name`. Teilen Sie dem Benutzer mit, dass er bereits ein Konto hat und sich damit anmelden muss, um die Verbindung zu verknüpfen; nennen Sie das Konto niemals namentlich. In dieser Transaktion werden `sso_start` und `magic_link` nicht angeboten, und der Schritt `identifier` leitet nicht zu einer Enterprise-Verbindung weiter.

Der Benutzer meldet sich mit den eigenen Methoden am bestehenden Konto an; ein Benutzer mit eingerichtetem zweitem Faktor wird danach gefragt. Der Schritt, der die Transaktion abschließt, öffnet keine Sitzung: Die Verbindung wird dem Konto zugeordnet, und die Antwort ist eine neue Transaktion in `federated_redirect` mit `redirect_url` für dieselbe Verbindung. Navigieren Sie das oberste Fenster dorthin; die Enterprise-Anmeldung wird nun wie üblich abgeschlossen. Wenn die Enterprise-Anmeldung nicht gestartet werden kann, lautet die neue Transaktion `identifier_pending`, und es folgt eine gewöhnliche Anmeldung.

Wer mit einem anderen Konto oder ohne den eingerichteten zweiten Faktor abschließt oder mit einer Anmeldung, die älter ist als die Verknüpfungsanfrage, verknüpft nichts und öffnet keine Sitzung: `409 transaction_state_conflict`. Eine Verknüpfungsanfrage, die abgelaufen ist (10 Minuten) oder bereits verwendet wurde, liefert `410 transaction_expired`. Eine Verknüpfungsanfrage wird unabhängig vom Ergebnis nur einmal verwendet. Zum Ablehnen rufen Sie `POST /fapi/v1/transactions/current:cancel` auf.

## Richtlinie der Organisation

Wenn die Autorisierungsanfrage an eine Organisation gebunden ist, wird die Anmelderichtlinie der Organisation nach dem ersten Faktor und unmittelbar vor dem Öffnen der Sitzung erneut geprüft:

- Die IP-Adresse des Clients steht nicht auf der Allowlist der Organisation: `403 ip_not_allowed`.
- Die Faktoren der Transaktion erfüllen die Richtlinie der Organisation nicht (eine Methode, die die Organisation nicht erlaubt, ein fehlender Faktor, oder ein Sicherheitsschlüssel bzw. Passkey außerhalb der AAGUID-Allowlist der Organisation): `403 no_allowed_method`.
- Die Richtlinie der Organisation kann nicht gelesen werden: `503 temporarily_unavailable`. Die Anmeldung schlägt fehl und wird nie ohne die Richtlinie fortgesetzt.

Es wird keine Sitzung geöffnet. Eine Ablehnung beim Abschluss der Transaktion entfernt das Transaktions-Cookie; ein `503` nach dem ersten Faktor lässt die Transaktion dort, wo sie war, und der Schritt kann wiederholt werden. Der Fehlerkörper nennt nie die Organisation, den Benutzer oder die IP-Adresse.

## Headless-Transaktionen mit DPoP-Bindung

Für eine Transaktion, die mit dem Header `DPoP` gestartet wurde, senden Sie einen neuen Nachweis mit demselben Schlüssel (`htm` `POST`, `htu` die URL des Schritts)
anstelle von `Idp-Csrf-Token`; es wird kein Cookie verwendet. Der Schritt, der die Transaktion abschließt, liefert
`authorization_response` genau einmal:

```json
{
  "state": "completed",
  "authorization_response": { "code": "<code>", "state": "<your state>", "iss": "https://example.keenauth.app" },
  "next_steps": [],
  "schema_version": 1,
  "expires_at": "2026-11-02T10:15:00Z"
}
```

Prüfen Sie, ob `state` und `iss` übereinstimmen, und tauschen Sie dann den Code bei `/oauth2/token` mit Ihrer `code_verifier` und einem DPoP-Nachweis
mit demselben Schlüssel ein. Ein Nachweis mit einem anderen Schlüssel liefert `invalid_grant`. Kann die Autorisierungsanfrage nicht mit einem Code enden (Zustimmung, rechtliche Bedingungen, eine Wahl der Organisation oder eine neue Anmeldung ist erforderlich oder der Zugriff wird verweigert), liefert der Schritt
`403 authorization_failed`, und das Mitglied `error` enthält den OAuth-Fehlercode; es wird kein Code ausgestellt.

## Fehler

| Status | Code | Wann |
| --- | --- | --- |
| 401 | `invalid_credentials` | Die Kennung oder das Passwort wird nicht akzeptiert. |
| 403 | `origin_not_allowed` | `Origin` oder `Idp-Csrf-Token` fehlt oder ist falsch. |
| 403 | `ip_not_allowed` | Die IP-Adresse des Clients steht nicht auf der Allowlist der Organisation. |
| 403 | `no_allowed_method` | Die Anmeldung erfüllt die Richtlinie der Organisation nicht. |
| 403 | `test_feature_not_in_production` | `otp_verify` oder `email_2fa` hat in einer Produktionsumgebung den festen Testcode `424242` erhalten. Der Versuch wird wie ein falscher Code gezählt. |
| 404 | `not_found` | Der Schrittname ist kein bekannter Schritt. |
| 409 | `transaction_state_conflict` | Der Schritt ist im aktuellen Zustand nicht verfügbar. |
| 409 | `session_limit_reached` | Der Benutzer hat das Sitzungslimit erreicht, und neue Sitzungen werden abgelehnt. |
| 410 | `transaction_expired` | Die Transaktion ist beendet. |
| 422 | `validation_failed` | Ein Feld fehlt oder ist ungültig. |
| 503 | `temporarily_unavailable` | `sso_start` konnte die Enterprise-Anmeldung nicht erreichen oder die Richtlinie der Organisation nicht lesen; versuchen Sie es erneut. |
| 401 | `invalid_dpop_proof` | Der DPoP-Nachweis `DPoP` fehlt, ist ungültig oder wurde wiederverwendet. |
| 403 | `authorization_failed` | Die DPoP-gebundene Transaktion wurde abgeschlossen, aber ihre Autorisierungsanfrage endete ohne Code. |

## Beispiel

```bash
curl -X POST https://example.keenauth.app/fapi/v1/transactions/current/steps/identifier \
  -H "Idp-Client: my-app/1.0.0 (node/22.0.0)" \
  -H "Origin: https://example.keenauth.app" \
  -H "Idp-Csrf-Token: $CSRF_TOKEN" \
  -H "Content-Type: application/json" \
  -b cookies.txt \
  -d '{"identifier":"jane@example.com"}'
```

## Personenbezogene Daten

Dieser Endpunkt verarbeitet personenbezogene Daten: Profil und Zugangsdaten der Endbenutzer. [Personenbezogene Daten in den KeenAuth-APIs](/docs/policies/personal-data) beschreibt, was gespeichert wird, wie lange es aufbewahrt wird und wie es gelöscht wird. Senden Sie in keinem Feld besondere Kategorien personenbezogener Daten (Gesundheit, biometrische Daten, Religion, politische Meinungen, sexuelle Orientierung).
