Skip to content

OpenID Connect flows, response modes and claims

This page is for operators and realm administrators. It covers what the authorization endpoint of a realm (/realms/<realm>/oauth2/authorize) accepts, and which claims the tokens and userinfo carry. The behaviour follows OpenID Connect Core 1.0, OAuth 2.0 Multiple Response Type Encoding Practices and OAuth 2.0 Form Post Response Mode.

Response types

response_type Flow Available to
code Authorization code (recommended; PKCE for public clients) every client with the authorization_code grant
id_token, id_token token Implicit (Core §3.2) clients with the implicit grant only
code id_token, code token, code id_token token Hybrid (Core §3.3) clients with the implicit grant only

Discovery (response_types_supported, grant_types_supported) lists the implicit and hybrid response types and the implicit grant only in a realm where a client can use them. That is a realm where a client has the implicit grant, or where Dynamic Client Registration may register it.

The implicit and hybrid flows are off by default

These flows return tokens through the browser, so OAuth 2.1 and FAPI no longer recommend them. They are there for OpenID Connect relying parties that cannot use the code flow. To switch them on for one client:

  • Console: open Clients → the client → Credentials and tick Implicit and hybrid flows (legacy).
  • Admin API: add implicit to the client's grantTypes.

HelixIAM refuses the switch (400, field grantTypes) in these cases:

Code Why
implicitNeedsCode The client must also have the authorization_code grant. Both flows are built on the authorization endpoint's code issuance.
implicitNotFapi The client requires a signed request object, certificate-bound access tokens or a JARM response mode. FAPI allows the code flow only.
implicitHighAssurance The realm uses the HIGH key-custody profile.

Dynamic Client Registration. A registration that asks for a response type with id_token or token (or for the implicit grant) needs the implicit grant. The realm administrator must allow that grant for registration (Provisioning → Dynamic Client Registration → allowed grant types → Implicit and hybrid (legacy)). It is never allowed by default. Such a client is registered with the authorization_code grant as well, and the registration response reports both.

What the authorization endpoint checks and returns

  • redirect_uri: must be one of the client's registered redirect URIs, compared exactly.
  • nonce: required whenever an ID token comes from the authorization endpoint (Core §3.2.2.1, §3.3.2.11).
  • Scope: openid is required.
  • Response mode:
  • fragment is the default.
  • form_post is also accepted.
  • query is refused (invalid_request): tokens are never put in a query string.
  • Errors: sent back in the same response mode as a success would be.
  • The ID token from the authorization endpoint:
  • carries nonce, at_hash with an access token and c_hash with a code;
  • the hash is that of the ID token's signing algorithm;
  • it carries the standard claims of the granted scopes.
  • The access token from the authorization endpoint:
  • lives at most 5 minutes;
  • no refresh token is ever issued with it.
  • Hybrid flow: the code is redeemed at the token endpoint as usual, with PKCE when the client sent a code_challenge.
  • Implicit flow: the code is never sent to the client.
  • Behind a reverse proxy: these responses carry the tokens in the Location header of the redirect. With many claims that header exceeds the 4–8 KB response-header buffer some proxies default to, and the proxy answers 502:
  • nginx: proxy_buffer_size 32k; proxy_buffers 8 32k;
  • ingress-nginx: the annotation nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"
  • Everything else is the same as the code flow: sign-in, prompt, max_age, consent, MFA, the session binding (sid, auth_time, acr) and the audit trail.

Response modes

response_mode For
query code (the default)
fragment implicit and hybrid (the default)
form_post every response type (OAuth 2.0 Form Post Response Mode)

With form_post, the authorization endpoint answers with a page whose form POSTs the response parameters to the redirect URI. The page submits itself with a script served by HelixIAM, and its content security policy only allows a form to the redirect URI's origin.

Claims

The standard claims of the profile, email, address and phone scopes (OpenID Connect Core §5.4) are released only when that scope is granted. A claim named in the claims request parameter (§5.5) is released too:

  • a claim named under id_token goes into the ID token;
  • a claim named under userinfo comes from userinfo.

The values have the JSON types of §5.1:

  • email_verified and phone_number_verified are booleans;
  • updated_at is seconds since the epoch, the last change of the account;
  • address is one JSON object.

Claims outside these scopes (custom attributes released by the claim mapping, roles, organizations) are not affected.

See also