Understanding OIDCLoginProtocol.SCOPE_PARAM in Keycloak

When integrating with Keycloak for OpenID Connect (OIDC) authentication, you might encounter code like:

clientSessionCtx.getClientSession()
    .setNote(OIDCLoginProtocol.SCOPE_PARAM, "openid");

This small line plays a big role in deciding whether you get an ID Token (and identity claims) or just an Access Token.


What is OIDCLoginProtocol.SCOPE_PARAM?

OIDCLoginProtocol.SCOPE_PARAM corresponds to the scope parameter in an OIDC authentication request. Scopes tell the Identity Provider (IdP) what kind of information and tokens the client is asking for.

In OIDC, the "openid" scope is mandatory to receive an ID token.


Case 1: Passing "openid"

Flow

When you set the scope to "openid", Keycloak treats this as an OpenID Connect request:

  1. OIDC flow is triggered instead of pure OAuth 2.0.

  2. Keycloak issues:

    • ID Token (JWT) containing user identity claims.

    • Access Token for API access.

    • Optionally, a Refresh Token.

  3. ID Token contains claims like:

    • sub (subject identifier)

    • name

    • email

    • preferred_username

    • auth_time

Example Output

ID Token (decoded):

{
  "iss": "https://auth.example.com/realms/myrealm",
  "sub": "b9a8c347-xxxx-xxxx-xxxx-4e0f9829e023",
  "preferred_username": "jatin",
  "email": "jatin@example.com",
  "auth_time": 1692349873,
  "iat": 1692349873,
  "exp": 1692353473
}

Access Token is still issued, containing authorization data.


Case 2: Not Passing "openid"

Flow

If you skip setting "openid", Keycloak defaults to pure OAuth 2.0:

  1. No ID Token is issued.

  2. You only get:

    • Access Token (for API calls)

    • Optionally, a Refresh Token.

  3. Limited claims are available, and they’re meant for authorization, not identity.

Example Output

Access Token only:

{
  "iss": "https://auth.example.com/realms/myrealm",
  "sub": "b9a8c347-xxxx-xxxx-xxxx-4e0f9829e023",
  "resource_access": {
    "my-client": { "roles": ["user"] }
  },
  "scope": "profile email"
}

Why This Matters

  • With "openid" → You’re requesting OIDC authentication and full identity info.

  • Without "openid" → You’re using OAuth 2.0 only, suitable for API calls where identity data isn’t needed.


Summary Table

Scenario "openid" Passed "openid" Not Passed
Protocol Mode OIDC OAuth 2.0 only
ID Token ✅ Present ❌ Not issued
Access Token ✅ Present ✅ Present
Identity Claims ✅ Available in ID Token ❌ Limited in Access Token
Use Case User login + profile retrieval API access without login

Key Takeaways

  • Always include "openid" in scope for login flows.

  • Without it, you won’t get ID tokens or full identity claims.

  • Forgetting this in custom Keycloak flows can silently break logic expecting identity info.

Comments

Popular posts from this blog

Handling Apple "Hide My Email" in Your Login System: Best Practices

Understanding the failedLogin() Method with Sequence Diagram