February 24, 2025

Understanding Multiple Login Events in Keycloak During Google SSO

Introduction

When implementing Single Sign-On (SSO) with Google as an Identity Provider (IdP) in Keycloak, you may notice that a single user login generates multiple login events—one for each client application. This can cause confusion, especially when debugging authentication flows or tracking user sessions.

In this blog post, we will explore why this happens, how to replicate it locally, and how to fix or control this behavior using Keycloak settings.

Why Do Multiple Login Events Occur in Keycloak During Google SSO?

This issue arises due to the OAuth 2.0 Authorization Code Flow with OpenID Connect (OIDC) that Google follows. When a user logs into one client application and then accesses another client application under the same Keycloak realm, Keycloak registers a separate login event for each client.

Key Factors Contributing to Multiple Login Events

  1. Google Uses a Shared Authentication Session:

    • When a user logs into Client1 via Google, Google creates a session.
    • When the user accesses Client2, Google detects the active session and automatically authenticates the user, without prompting for credentials.
    • Even though the user did not re-enter credentials, Keycloak registers a new login event.
  2. Keycloak Treats Each Client Separately:

    • Keycloak considers each client as an independent entity.
    • When a user accesses multiple clients, even within the same session, Keycloak triggers separate login events for tracking purposes.
  3. Google Login Response Includes New ID Tokens Per Client:

    • When Keycloak redirects the user to Google for login, Google issues a new ID Token for each client.
    • Even though the user remains authenticated, the new token issuance results in a new event.
  4. Keycloak Logs Each Authentication Request as a New Event:

    • Keycloak logs a separate authentication event each time an authentication request is made to the IdP (Google), even if credentials are not re-entered.

How to Configure Session Handling in Keycloak

Keycloak allows you to control whether users share the same session across multiple clients or have separate sessions per client. This can help manage login events more effectively.

Using the Same Session Across Clients

To enforce session sharing across multiple clients:

  1. Navigate to Realm SettingsTokens

  2. Adjust the SSO Session Idle Timeout and SSO Session Max Lifespan to maintain session continuity.

  3. Ensure that Full Scope Allowed is enabled for clients to share user sessions.

  4. Use the SameSite=None cookie setting to ensure session continuity in cross-client authentication.


Controlling the Number of Sessions in Keycloak

To limit how many active sessions a user can have:

  1. Navigate to Realm SettingsSessions.

  2. Configure Maximum Sessions per User to define the maximum concurrent sessions allowed.

  3. Enable Single Sign-Out so that logging out from one session logs the user out from all active sessions.

  4. Adjust Session Limits per client under Clientsclient1Settings.

These settings help you control how sessions are handled across different clients and prevent excessive login events.

Using Separate Sessions Per Client

If you need independent sessions for each client:

  1. Disable Full Scope Allowed for the client under Clientsclient1 or client2.

  2. Set Client Session Idle Timeout and Client Session Max Lifespan separately for each client under Advanced Settings.

  3. Use the prompt=login parameter to force Google authentication for each client.

How to Replicate Multiple Login Events Locally

Step 1: Set Up Keycloak Locally

  1. Start Keycloak in development mode:
    ./kc.sh start-dev
    
  2. Create a new realm (e.g., my-realm).
  3. Create two clients (client1 and client2) in the same realm.
  4. Configure both clients to use Google as an Identity Provider:
    • Go to Identity ProvidersAdd providerGoogle.
    • Configure the Client ID and Client Secret from your Google Cloud Console.
    • Set Redirect URIs for both clients (http://localhost:8081/* and http://localhost:8082/*).
    • Enable Standard Flow and Implicit Flow.

Step 2: Run Two Applications Using Keycloak Authentication

Run two separate web applications:

  • Client1 → http://localhost:8081
  • Client2 → http://localhost:8082

Ensure both applications:

  • Use the same Keycloak realm.
  • Have client_id configured accordingly.
  • Redirect to Google for authentication.

Step 3: Simulate an SSO Login Flow

  1. Open an Incognito browser window.
  2. Navigate to http://localhost:8081 and initiate login.
  3. Authenticate using Google.
  4. Open another tab and go to http://localhost:8082.
  5. Notice that the second application logs in without prompting for credentials.
  6. Check Keycloak logs under EventsLogin Events, and you will see two separate login entries.

How to Fix or Control This Behavior

1. Enable Single Session Across Clients

By default, Keycloak logs each client authentication as a separate event. However, we can enforce session sharing across clients:

  • Go to Realm SettingsTokens
  • Increase the SSO Session Max Lifespan to keep the session active longer.
  • Increase SSO Session Idle Timeout to avoid unnecessary re-authentication.

2. Adjust Client Session Settings

Each client may have different session handling settings. To standardize session behavior across clients:

  • Navigate to Clientsclient1 or client2.
  • Under Advanced Settings, adjust the SSO Session Idle Timeout.
  • Ensure Full Scope Allowed is enabled to share user sessions across multiple clients.

3. Enforce User Session Limits

To control how many login events are generated:

  • Go to Realm SettingsSessions.
  • Set Maximum Sessions per User to 1 to ensure a single session is active at a time.
  • Enable Single Sign-Out to ensure logging out from one client logs the user out from all clients.

4. Modify Google Authentication Prompt Behavior

If you want Google to prompt users for login every time (rather than using an existing session), modify the authentication request:

  • In the Keycloak Identity Provider settings for Google, set the prompt parameter:
    prompt=select_account
    
  • This forces Google to show the account selection screen every time a login is requested.

5. Control Login Event Logging in Keycloak

If you want to reduce unnecessary login event logging, you can modify Keycloak’s logging levels:

./kc.sh start-dev --log-level=INFO

Or update the logging configuration in standalone.xml:

<logger category="org.keycloak.events">
    <level name="WARN"/>
</logger>

How Custom SSO Calls Trigger Login Events in Keycloak

Custom authentication flows in Keycloak can also trigger login events. Here’s how:

  1. Using Keycloak REST API for Login:

    • When calling the POST /realms/{realm}/protocol/openid-connect/token endpoint with valid credentials, Keycloak registers a login event.
  2. Programmatic Login via JavaScript Adapter:

    keycloak.login({ redirectUri: 'http://localhost:8081/home' });
    
    • This triggers a login event for the client initiating the request.
  3. Custom Authentication Flows:

    • Implementing a custom authenticator in Keycloak SPI that handles login logic can generate login events.
  4. Silent Authentication Requests:

    • When the frontend attempts a silent login via check-sso, Keycloak may log an event if a session refresh is required.

Conclusion

Experiencing multiple login events when using Google SSO with Keycloak is a common scenario due to how OAuth 2.0 and OIDC work. The main reasons include Google’s session management, Keycloak’s client separation, and Google issuing new ID tokens per client.

By following the recommended fixes and understanding how custom SSO calls interact with Keycloak, you can control and optimize login event handling effectively.