feat(cognito): hosted login page, PKCE and refresh-token grant
The pool's own users can now sign in through /oauth2/authorize the way apps expect Cognito to work: without identity_provider (or with COGNITO) the browser lands on a hosted login page, and a correct password redirects to the registered callback with a one-time code. - GET/POST /cognito-idp/login (and /login on custom domains), with a CSRF cookie and the same password rules and Pre/Post Authentication triggers as USER_PASSWORD_AUTH; wrong passwords, unknown and unconfirmed users get the same answer until the password is right - a one-hour browser session, so the next authorize skips the form unless it sends prompt=login, and /logout with LogoutURLs validation - PKCE S256 on both hosted and federated codes, and nonce in the ID token - refresh_token grant on /oauth2/token - codes now fire Pre Token Generation with TokenGeneration_HostedAuth instead of skipping the trigger
This commit is contained in:
+30
-10
@@ -75,9 +75,9 @@ AWS-shaped `/oauth2/authorize` and `/oauth2/idpresponse` endpoints to the config
|
||||
OIDC provider, exchanges the returned code, provisions or reconciles the federated user,
|
||||
and issues a Cognito authorization code for the registered callback.
|
||||
|
||||
Only `ProviderType=OIDC` is supported by this flow. Floci does not provide a built-in hosted
|
||||
UI and does not implement social providers such as Google, Facebook, Login with Amazon or
|
||||
SignInWithApple.
|
||||
Only `ProviderType=OIDC` is supported by this flow. Floci does not implement social providers
|
||||
such as Google, Facebook, Login with Amazon or SignInWithApple. The pool's own users sign in on
|
||||
the hosted login page instead (see Well-Known And OAuth Endpoints below).
|
||||
|
||||
Two deliberate divergences from AWS, both consequences of not calling out to a third
|
||||
party:
|
||||
@@ -280,8 +280,8 @@ up, so an oversized request naming something that does not exist reports the req
|
||||
problem rather than `ResourceNotFoundException`, and an update violating both reports them
|
||||
in one message with the asset list first.
|
||||
|
||||
Branding is presentation for the hosted UI, which Floci does not serve, so it is stored
|
||||
and returned rather than rendered. Two divergences follow from that:
|
||||
Branding is presentation for the hosted UI. Floci's hosted login page does not apply it, so it
|
||||
is stored and returned rather than rendered. Two divergences follow from that:
|
||||
|
||||
- **`Settings` is stored opaquely.** AWS validates it against a deep schema, rejecting
|
||||
unknown properties with `Invalid settings provided. Validation errors: [{property:
|
||||
@@ -304,17 +304,37 @@ and returned rather than rendered. Two divergences follow from that:
|
||||
| `GET /{userPoolId}/.well-known/jwks.json` | JSON Web Key Set for JWT validation |
|
||||
| `GET /cognito-idp/oauth2/authorize` | OIDC authorization-code start endpoint |
|
||||
| `GET /cognito-idp/oauth2/idpresponse` | OIDC provider callback endpoint |
|
||||
| `POST /cognito-idp/oauth2/token` | OAuth authorization-code and client-credentials token endpoint |
|
||||
| `GET, POST /cognito-idp/login` | Hosted login page for the pool's own users |
|
||||
| `GET /cognito-idp/logout` | Ends the hosted login session |
|
||||
| `POST /cognito-idp/oauth2/token` | OAuth authorization-code, refresh-token and client-credentials token endpoint |
|
||||
|
||||
The OAuth endpoints support browser-style OIDC authorization-code sign-in as well as the
|
||||
emulator-friendly client-credentials flow:
|
||||
|
||||
- `GET /cognito-idp/oauth2/authorize` validates the app client and callback, then redirects
|
||||
to the configured provider with an opaque state and nonce.
|
||||
- `GET /cognito-idp/oauth2/authorize` validates the app client and callback. With
|
||||
`identity_provider` naming an OIDC provider it redirects there with an opaque state and nonce.
|
||||
Without `identity_provider`, or with `identity_provider=COGNITO`, the pool's own users sign in
|
||||
on the hosted login page; the client must list `COGNITO` in `SupportedIdentityProviders` (the
|
||||
default when none are given).
|
||||
- `GET /cognito-idp/login` shows a user name (or email) and password form. A correct password
|
||||
redirects to the registered callback with a one-time authorization code and `state`, and starts
|
||||
a one-hour browser session (the `cognito` cookie), so the next authorize request returns a code
|
||||
without the form unless it sends `prompt=login`. Wrong passwords, unknown users and
|
||||
unconfirmed users get the same answer until the password is right. Users with a temporary
|
||||
password, MFA or a pending reset are told so; those steps are not served on the page yet.
|
||||
- `GET /cognito-idp/logout?client_id=...&logout_uri=...` ends the session and redirects to
|
||||
`logout_uri`, which must be one of the client's `LogoutURLs`. With `redirect_uri` and
|
||||
`response_type=code` instead, it ends the session and shows the login page again.
|
||||
- PKCE: send `code_challenge` with `code_challenge_method=S256` to authorize, and the matching
|
||||
`code_verifier` when redeeming the code. `nonce` is copied into the ID token.
|
||||
- Codes from the hosted login and from federated sign-in fire the Pre Token Generation trigger
|
||||
with `triggerSource=TokenGeneration_HostedAuth`, and the hosted login fires Pre and Post
|
||||
Authentication.
|
||||
- `GET /cognito-idp/oauth2/idpresponse` consumes the provider state, exchanges the provider
|
||||
code and redirects to the registered callback with a one-time Cognito authorization code.
|
||||
- `POST /cognito-idp/oauth2/token` redeems that authorization code once, or issues a machine
|
||||
token for `grant_type=client_credentials`.
|
||||
- `POST /cognito-idp/oauth2/token` redeems that authorization code once, exchanges a
|
||||
`refresh_token` for new access and ID tokens, or issues a machine token for
|
||||
`grant_type=client_credentials`.
|
||||
|
||||
`POST /cognito-idp/oauth2/token` is intentionally emulator-friendly rather than full Cognito parity:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user