NashTech Blog

Table of Contents

Welcome back to this Keycloak series. This is the second blog, where we continue understanding Keycloak step by step.

In the previous blog, Keycloak Basics: Concepts, Protocols, and Configuration we covered the Keycloak fundamentals and set up everything needed to get authentication working:

  • Realms
  • Clients
  • Users
  • Roles
  • Assigning roles to users using the Admin Console

So far, we logged in through the Keycloak UI and verified that it issued tokens successfully. However, we haven’t yet explored the information inside them or how they are used by services in real-world systems.

In this guide, we shift the focus to Keycloak tokens and authentication flow. Rather than introducing new configurations, we concentrate on understanding the tokens themselves. We will cover their types and how clients use them. We will also see how they are validated, refreshed, and invalidated. Finally, we will decode a token and inspect its claims in a real scenario.

Token Basics

A token is a short-lived credential issued by Keycloak after a user successfully logs in. Instead of sending usernames and passwords on every request, applications use this token to prove who the user is.

Keycloak handles authentication and then issues tokens that applications can trust. The application never sees or stores user passwords — it only works with tokens.

In OAuth 2.0 and OpenID Connect flows, tokens are the final result of the authentication process. After a successful login, Keycloak generates and returns tokens. These tokens serve different purposes. For example, they access secured APIs, maintain active sessions, or convey identity details depending on their type.

Types of Tokens in Keycloak

1. Access Token

The access token is used by applications to authorize requests. It is sent with every secured API call in the request header:

Authorization: Bearer <access_token>

Access tokens are short-lived by default, which limits the impact if a token is leaked or compromised. They contain:

  • User identity
  • Roles
  • Scopes
  • Client information

This is the token that backend APIs validate to decide whether a request should be accepted.

2. ID Token

The ID token is used for authentication, meaning it proves who the user is. It is mostly consumed by frontend applications after login and is not intended for API access. ID tokens are also short-lived, reducing the risk if they are exposed.

It typically contains:

  • User ID
  • Username or email
  • Session information

In most cases, backend services avoid using the ID token for authorization. The ID token is designed to verify who the user is. It is not meant to determine what the user is allowed to do.

3. Refresh Token

The refresh token is used to obtain a new access token when the current one expires. It has a longer lifespan than the access token. Keycloak issues it only to trusted clients, because anyone possessing a refresh token can generate new access tokens.

Its main purpose is to:

  • Avoid frequent re-authentication
  • Maintain user sessions seamlessly

The refresh token has a longer lifespan and higher privileges, so you must store and handle it securely. Exchange it only with Keycloak at the token endpoint — never send it to backend APIs.

Token Flow Walkthrough

This section demonstrates the token lifecycle using Postman and verifies the session using the Keycloak Admin Console. This process does not involve any application integration.

0. Enable the Direct Access Grants

This guide uses the Keycloak configuration from the previous blog, including realms, clients, users, and roles, with just one small modification required. We will be logging in using a username and password. Therefore, we need to enable Direct Access Grants in the demo-app client settings. This allows the client to request tokens directly using user credentials.

Enable the Direct Access Grants Authentication Flow for the Client

1. Login and Get Tokens

Use Postman to authenticate with Keycloak and obtain tokens using a username and password.

Method: POST

URL: http://localhost:8080/realms/demo-realm/protocol/openid-connect/token

Headers: Content-Type: application/x-www-form-urlencoded

Body (x-www-form-urlencoded)

grant_type=password
client_id=demo-app
client_secret=<your-client-secret>
username=john.doe
password=john

The examples in this blog use demo values based on the Keycloak setup from the previous blog — including host (localhost), realm (demo-realm), client ID (demo-app), client secret, and user credentials (john.doe / john). If you are using your own Keycloak setup, replace these values accordingly.

Login and Get Tokens using Postman

Token Format

Keycloak issues tokens in JWT (JSON Web Token) format. A JWT is a compact, self-contained token that carries all required information within itself.

A JWT has three parts:

header.payload.signature
  • Header – contains metadata about the token, such as the signing algorithm
  • Payload – contains claims like user details, roles, scopes, and expiry
  • Signature – ensures the token has not been tampered with

JWTs are stateless, meaning the server does not need to store session data. All the information needed to validate and authorize a request is already inside the token.

2. Verify Login Session

After obtaining the tokens, you can verify the login directly in the Keycloak Admin Console. First, navigate to Users → Sessions, and then select the logged-in user.

If the authentication was successful, you will see an active session listed for that user. This confirms that Keycloak authenticated the user successfully. It also shows that Keycloak created and is actively maintaining a session for them.

Verify Login Session in Keycloak Admin Console

3. Decode the Token

Once you have obtained the access_token from Keycloak using the password grant, you can decode it. This allows you to inspect its contents and understand the information it carries. This is useful for seeing the user details, roles, and other claims included in the token.

  1. Copy the access token value from Postman’s response.
  2. Open https://jwt.io/ in your browser.
  3. Paste the token into the “Encoded” field on the left.
  4. The decoded payload will appear on the right, where you can see all the claims included in the token.
Decode the Token via jwt.io

Key Claims in Keycloak Tokens

JWT tokens contain claims, which are key–value pairs holding information about the user, client, and the token itself. Keycloak-issued tokens are validated against these claims to verify things like issuer, audience, expiration, and user roles.

Some commonly used claims include:

  • sub (Subject): Uniquely identifies the authenticated user.
  • iss (Issuer): Identifies the issuer of the token — the Keycloak realm that issued it. This ensures the token came from a trusted realm.
  • aud (Audience): Specifies who the token is intended for, usually a client. Ensures the token is being used by the correct consumer.
  • exp (Expiration Time): Defines when the token expires. Tokens are rejected once this time is reached.
  • iat (Issued At): Indicates when the token was issued.
  • scope: Represents the scopes granted to the client for this token.
  • realm_access / resource_access: Contain role information.
    • realm_access holds realm-level roles
    • resource_access holds client-specific roles

Roles and permissions are included directly in the token’s claims. That’s how, the receiving service can instantly decide the user’s identity and access rights. This eliminates the need for extra requests to Keycloak during authorization.

4. Refresh the Access Token

Before logging out, you can use the refresh token. It allows you to obtain a new access token without re-entering the username and password.

Method: POST

URL: http://localhost:8080/realms/demo-realm/protocol/openid-connect/token

Headers: Content-Type: application/x-www-form-urlencoded

Body (x-www-form-urlencoded)

client_id=demo-app
client_secret=<<your-client-secret>>  
refresh_token=<your-refresh_token>
grant_type=refresh_token
Refresh the Access Token using Postman

5. Inactive the Token

To terminate the user session, call the Keycloak logout endpoint using the refresh token. This invalidates the session and prevents any further token refresh.

Method: POST

URL: http://localhost:8080/realms/demo-realm/protocol/openid-connect/logout

Headers: Content-Type: application/x-www-form-urlencoded

Body (x-www-form-urlencoded)

client_id=demo-app
client_secret=<your-client-secret>
refresh_token=<your-refresh_token>
Inactive the Token using Postman

6. Introspect the Token

After logout, you can verify the token state by using Keycloak’s token introspection endpoint.

Method: POST

URL: http://localhost:8080/realms/demo-realm/protocol/openid-connect/token/introspect

Headers: Content-Type: application/x-www-form-urlencoded

Body (x-www-form-urlencoded)

client_id=demo-app
client_secret=<your-client-secret>
token=<your-access_token>
Introspect the Token using Postman

Conclusion

In this blog, we revisited Keycloak tokens and explored their lifecycle in detail using Postman. We walked through each step, from login and token issuance to refresh, logout, and introspection. This gives us a solid foundation for using them confidently in real-world systems.

In the next blog, Secure Spring Boot APIs Using Keycloak, we will move beyond Keycloak itself and focus on application integration. We will explore how applications consume these tokens to secure and authorize APIs, including validating access tokens, extracting roles and scopes, and enforcing authorization at the API level

Picture of Nadra Ibrahim

Nadra Ibrahim

Software Consultant

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top