June 12, 2025

Understanding authSession.setAction(AUTHENTICATE) and Related Settings in Keycloak Login Flows

When customizing login flows in Keycloak—especially during first login with an identity provider (IdP)—you often interact with the AuthenticationSessionModel and AuthenticatedClientSessionModel. If you’ve looked at lines like the following and wondered what they do or why they’re necessary, this blog is for you:

authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
authSession.setClientNote(OIDCLoginProtocol.ISSUER, Urls.realmIssuer(session.getContext().getUri().getBaseUri(), realm.getName()));
authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, "openid");
authSession.setAction(AuthenticatedClientSessionModel.Action.AUTHENTICATE.name());

๐ŸŽฏ Problem Statement

In a custom login flow, particularly when modifying the first broker login flow, missing or incorrect session attributes can result in:

  • invalid_request or invalid_signature errors

  • missing id_tokens

  • broken post-login steps like account linking or consent pages

  • failure to issue access or refresh tokens

To ensure smooth interoperability between Keycloak and the OIDC protocol, it's essential to explicitly configure the authSession.


๐Ÿงช What Each Line Does and Why It Matters

1️⃣ authSession.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);

  • Purpose: Tells Keycloak that the current session is using the openid-connect protocol.

  • Why it's important: Without it, Keycloak might not route the request properly or issue OIDC-compliant tokens.


2️⃣ authSession.setClientNote(OIDCLoginProtocol.ISSUER, <issuer-url>);

  • Purpose: Sets the issuer for the session, which is later embedded in the id_token.

  • Why it's important: If this doesn’t match the value expected by the client, token verification will fail with an "invalid issuer" error.


3️⃣ authSession.setClientNote(OIDCLoginProtocol.SCOPE_PARAM, "openid");

  • Purpose: Specifies the OAuth2/OIDC scopes requested by the client.

  • Why it's important: The "openid" scope is required to receive an id_token. If omitted, your application won’t get identity claims.


4️⃣ authSession.setAction(AUTHENTICATE);

  • Purpose: Sets the session's current action to AUTHENTICATE, signaling Keycloak that the user is in the authentication step.

  • Why it's important:

    • Drives what Keycloak will do next (e.g., show login form, redirect to consent).

    • Affects what happens after authentication—like whether required actions or token exchange steps will run.

    • Without it, the flow can end prematurely or fail entirely.


๐Ÿงพ Available Actions in AuthenticatedClientSessionModel.Action

These enum values define what stage the user is currently in within the Keycloak login or token flow:

Action Description
AUTHENTICATE User is currently authenticating (e.g., login form, social login)
LOGGED_IN Authentication is completed successfully
REQUIRED_ACTIONS User must perform additional steps (verify email, update password, etc.)
CODE_TO_TOKEN The client is exchanging an authorization code for tokens (OAuth2 Code Flow)
OAUTH_GRANT The user is granting consent to the client for requested scopes
REGISTER User is undergoing the registration flow

These values control what happens next in the flow, which UI screens are shown, and which server-side logic gets triggered.


๐Ÿงฉ Where You Typically Use This

These session settings are commonly found in:

  • IdpCreateUserIfUniqueAuthenticator (default first-login logic)

  • Your custom Authenticator or AuthenticatorFactory when extending login flow

  • SPIs that handle custom logic during IdP login or user account creation


✅ Best Practices

  • Always set the protocol, scope, and issuer for custom login flows.

  • Set the action to match the current step (AUTHENTICATE, REGISTER, etc.).

  • Ensure you do this before token issuance or response handling steps.


๐Ÿšซ What Happens If You Skip These

Setting Without It...
setProtocol(...) Flow might not work; tokens might not be generated.
setClientNote(ISSUER) id_token may have wrong issuer → validation fails.
setClientNote(SCOPE_PARAM) No id_token, breaking OIDC login.
setAction(AUTHENTICATE) Flow breaks midway or doesn't trigger post-login handlers.

๐Ÿง  Conclusion

Customizing Keycloak login flows is powerful but requires careful handling of session metadata. These authSession configurations are not optional—they are critical building blocks for a stable and secure authentication experience.

If you're implementing a custom Authenticator or enhancing the first-broker-login flow, make sure to explicitly set these session details to avoid unpredictable errors and ensure a smooth experience for both users and client applications.