Skip to content

Spring Boot service that bridges RFID-based identification to Keycloak token exchange and role extraction. It allows clients to authenticate either via an RFID attribute stored on a Keycloak user or via username/password, and to decode roles from a JWT.

License

Notifications You must be signed in to change notification settings

stylepatrick/keycloak-rfid-adapter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Keycloak RFID Adapter

Spring Boot service that bridges RFID-based identification to Keycloak token exchange and role extraction. It allows clients to authenticate either via an RFID attribute stored on a Keycloak user or via username/password, and to decode roles from a JWT.

What it does

  • Authenticates by RFID using Keycloak token exchange (client-credentials -> user token).
  • Authenticates by username/password using the password grant.
  • Extracts realm and client roles from a JWT and returns them in a simple DTO.

Endpoints

POST /auth

Authenticate using either RFID or username/password.

Request body (JSON):

{
  "rfid": "1234567890"
}

or

{
  "username": "alice",
  "password": "secret"
}

Response: raw token response from Keycloak (map of token fields).

Error behavior:

  • 403 if RFID is not found or password is invalid.
  • 409 if RFID maps to multiple users.
  • 401 if user is disabled or credentials are missing.

RFID lookup uses a Keycloak user attribute named RFID.

POST /auth/refresh

Refresh an access token using a refresh token.

Request body (JSON):

{
  "refreshToken": "<refresh_token>"
}

Response: raw token response from Keycloak (map of token fields).

POST /auth/details

Extract roles and basic profile fields from a JWT.

Headers:

  • Authorization: Bearer <jwt>

Response (JSON):

{
  "username": "alice",
  "name": "Alice",
  "lastName": "Doe",
  "email": "alice@example.com",
  "realmRoles": ["user", "admin"],
  "clientRoles": {
    "account": ["view-profile"],
    "my-client": ["read", "write"]
  }
}

Configuration

Application Configuration

Configured via application.yaml with environment variable overrides:

keycloak:
  base-url: ${KEYCLOAK_AUTH}
  realm: ${KEYCLOAK_REALM}
  client-id: ${KEYCLOAK_CLIENT}
  client-secret: ${KEYCLOAK_CLIENT_SECRET}

cors:
  allowed-origins: ${CORS_ALLOWED_ORIGINS}

Required environment variables:

  • KEYCLOAK_AUTH (e.g., http://localhost:8180/auth)
  • KEYCLOAK_REALM
  • KEYCLOAK_CLIENT
  • KEYCLOAK_CLIENT_SECRET
  • CORS_ALLOWED_ORIGINS (e.g., http://localhost:3000,http://localhost:8080)

Optional profile:

  • dev profile uses src/main/resources/application-dev.yaml with sample values.

Additional features:

  • Virtual threads enabled via Spring Boot 4.0.2

Keycloak Configuration

The service requires a Keycloak client with service account enabled. The service account must have the following realm-management client roles assigned:

Required Keycloak server feature:

  • Token exchange must be enabled at Keycloak startup: KC_FEATURES=token-exchange

Required service account roles:

  • query-users - Required to search for users by RFID attribute
  • view-users - Required to read user details
  • impersonation - Required to perform token exchange and impersonate users

To configure in Keycloak:

  1. Ensure Keycloak is started with token exchange enabled: KC_FEATURES=token-exchange
  2. Create a new client (e.g., rfid-adapter)
  3. Enable Service accounts roles in the client settings
  4. Go to the Service Account Roles tab
  5. Add the client role filter for realm-management
  6. Assign the roles: query-users, view-users, and impersonation
  7. Add an RFID user attribute to users for RFID-based authentication:
    • Navigate to Users → Select a user → Attributes tab
    • Add attribute key: RFID, value: the RFID number (e.g., 1234567890)
    • The service queries users by this attribute to match RFID cards to user accounts

Build and run

Prerequisites:

  • Java 25 (configured in pom.xml)

Run locally:

./mvnw spring-boot:run

Run with dev profile:

./mvnw spring-boot:run -Dspring-boot.run.profiles=dev

Build jar:

./mvnw package

Run jar:

java -jar target/keycloak-rfid-adapter-0.0.1-SNAPSHOT.jar

Docker

Build the jar first, then build the image:

./mvnw package
docker build --build-arg JAR_FILE=target/keycloak-rfid-adapter-0.0.1-SNAPSHOT.jar -t keycloak-rfid-adapter:local .

Run:

docker run --rm -p 8080:8080 \
  -e KEYCLOAK_AUTH=http://host.docker.internal:8180/auth \
  -e KEYCLOAK_REALM=REALM \
  -e KEYCLOAK_CLIENT=rfid-adapter \
  -e KEYCLOAK_CLIENT_SECRET=change-me \
  keycloak-rfid-adapter:local

Project layout

  • src/main/java/stylepatrick/keycloakrfidadapter Spring Boot app, controllers, services.
  • src/main/resources/application.yaml base configuration.
  • Dockerfile runtime image (Temurin JRE 25).

Notes

  • Token exchange uses the Keycloak Admin client to resolve user ID by RFID and then exchanges for a user token.
  • /auth/details does not validate signature; it decodes the JWT payload and extracts claims.
  • CORS is configured via CORS_ALLOWED_ORIGINS environment variable.

About

Spring Boot service that bridges RFID-based identification to Keycloak token exchange and role extraction. It allows clients to authenticate either via an RFID attribute stored on a Keycloak user or via username/password, and to decode roles from a JWT.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published