Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Backend-for-Frontend Keycloak Extension

This module is a Keycloak realm resource provider extension.

Build

mvn clean package

Deploy to Keycloak

Copy the built JAR from target/ into your Keycloak providers/ directory, then rebuild/start Keycloak:

cp target/Backend-for-Frontend-1.0-SNAPSHOT.jar /path/to/keycloak/providers/
kc.sh build
kc.sh start

Endpoints

After deployment, the extension is available under:

  • POST /realms/{realm-name}/bff/login/start
  • POST /realms/{realm-name}/bff/login/otp
  • GET /realms/{realm-name}/bff/me
  • POST /realms/{realm-name}/bff/logout
  • POST /realms/{realm-name}/bff/backend/call

/login is still available as an alias for /login/start.

For browser-originated POST endpoints (/login, /login/start, /login/otp, /logout, /backend/call), the BFF validates Origin/Referer against the configured CSRF policy.

Step 1: start login

{
  "username": "user@example.com",
  "password": "secret"
}

Possible responses:

  • {"status":"ok", ...} with Set-Cookie when password-only login is accepted.
  • {"status":"otp_required","loginId":"...", ...} when OTP step must be completed.

Step 2: finish OTP challenge

{
  "loginId": "otp-challenge-id",
  "password": "secret",
  "otp": "123456"
}

A successful response returns {"status":"ok", ...} and issues the BFF session cookie.
The OTP step always requires the password to be submitted again and does not persist plaintext passwords server-side.

Validate current session

GET /realms/{realm-name}/bff/me validates BFF_SESSION and returns user/session metadata.

Call downstream backend as the logged-in user

POST /realms/{realm-name}/bff/backend/call

{
  "method": "GET",
  "path": "/orders?limit=10",
  "headers": {
    "Accept": "application/json"
  }
}

The BFF validates the BFF_SESSION, refreshes the Keycloak access token when needed, and forwards:

  • Authorization: Bearer <access_token>
  • a strict allow-list of caller-provided headers (for example Accept, Content-Type, If-*, and tracing headers)

to the configured backend target.

Provider Configuration

The BFF now needs an OIDC client configuration to mint and refresh tokens for backend propagation.

Set these provider keys in your Keycloak server config file:

  • local install: <keycloak-home>/conf/keycloak.conf
  • container image: /opt/keycloak/conf/keycloak.conf

Example keycloak.conf entries:

spi-realm-restapi-extension-bff-oidc-client-id=bff-client
spi-realm-restapi-extension-bff-oidc-client-secret=change-me
spi-realm-restapi-extension-bff-oidc-token-base-url=https://sso.example.com/
spi-realm-restapi-extension-bff-backend-base-url=https://api.example.com/
spi-realm-restapi-extension-bff-session-store-mode=single-use-object
spi-realm-restapi-extension-bff-session-ttl-seconds=28800
spi-realm-restapi-extension-bff-backend-timeout-seconds=10
spi-realm-restapi-extension-bff-max-in-memory-sessions=20000
spi-realm-restapi-extension-bff-csrf-allowed-origins=https://app.example.com,https://admin.example.com

Config keys:

  • oidc-client-id (required): confidential/public client used for password and refresh grants.
  • oidc-client-secret (optional): required for confidential clients.
  • oidc-token-base-url (required): absolute HTTPS base URL used for token and refresh POST requests. For local development, loopback HTTP URLs (http://localhost/..., http://127.0.0.1/..., http://[::1]/...) are also accepted.
  • backend-base-url (required for /backend/call): base URL allow-list target for proxy calls.
  • session-store-mode: single-use-object (default, distributed) or in-memory.
  • session-ttl-seconds: max BFF session lifetime (default 28800).
  • backend-timeout-seconds: timeout for token/backend HTTP requests (default 10).
  • max-in-memory-sessions: cap used only for in-memory mode.
  • csrf-allowed-origins: optional comma-separated origin allow-list for browser-originated POST endpoints (/login, /login/start, /login/otp, /logout, /backend/call); when omitted, strict same-origin is enforced.

CSRF configuration examples

Same-origin deployment (recommended default):
If your frontend is served from the same origin as Keycloak/BFF, omit csrf-allowed-origins. Requests with Origin/Referer are accepted only when they match the Keycloak/BFF origin.

# No csrf-allowed-origins setting required
spi-realm-restapi-extension-bff-oidc-client-id=bff-client
spi-realm-restapi-extension-bff-oidc-token-base-url=https://sso.example.com/

Cross-origin frontend deployment:
If your frontend is hosted on a different origin, set every allowed browser origin explicitly.

spi-realm-restapi-extension-bff-csrf-allowed-origins=https://app.example.com,https://admin.example.com

Use origin values only (scheme://host[:port]), without paths or trailing route segments. For local development, include exact dev origins, for example http://localhost:5173.

Local development without HTTPS

When Keycloak runs locally over HTTP, set oidc-token-base-url to a loopback URL:

spi-realm-restapi-extension-bff-oidc-token-base-url=http://localhost:8080/

Only loopback HTTP hosts are accepted (localhost, 127.0.0.1, ::1). Non-loopback hosts still require HTTPS.

If oidc-token-base-url is missing or invalid, login and token exchange requests fail closed with a server misconfiguration error.

Backend Validation Path

The downstream backend should validate Keycloak bearer tokens, not the BFF_SESSION cookie:

  • JWT validation with Keycloak JWKS (/realms/{realm}/protocol/openid-connect/certs), or
  • token introspection (/realms/{realm}/protocol/openid-connect/token/introspect) for opaque/reference tokens.

Alpine.js demo app

A small Alpine.js test app is available in examples/frontend. An import-ready demo client configuration is available at examples/client.json. A Docker Compose setup that starts Keycloak + demo backend + demo frontend is available at examples/docker/docker-compose.yml.

Quick start:

cd examples/docker
docker compose up --build

Manual frontend quick start:

cd examples/frontend
cp .env.example .env
npm install
npm run dev

See examples/frontend/README.md for details.

About

A Keycloak realm resource provider that keeps tokens server-side, issues BFF_SESSION cookies, and proxies backend calls.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages