Framework Adapters
The general pattern
Section titled “The general pattern”Every framework integration follows the same two-role model:
- Frontend / OIDC client: any library that implements the Authorization Code + PKCE flow (keycloak-js for browsers, AppAuth for mobile, MSAL for Microsoft stacks, etc.).
- Backend / resource server: any library that validates Bearer JWTs against the realm’s JWKS endpoint.
The key insight is that the backend does not need a Keycloak-specific library. It only needs a library that can validate a JWT against a JWKS URL — which is a standard feature of every mature OAuth2/OIDC ecosystem.
Spring Boot (Spring Security OAuth2 Resource Server)
Section titled “Spring Boot (Spring Security OAuth2 Resource Server)”Add the Spring Security OAuth2 Resource Server dependency to your pom.xml:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-resource-server</artifactId></dependency>Then point Spring at your realm’s issuer URI. Spring automatically fetches the JWKS, verifies incoming JWTs, and populates SecurityContextHolder with the decoded claims:
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: http://localhost:8080/realms/my-appSpring Security derives the JWKS URL automatically from the issuer URI by appending /protocol/openid-connect/certs (via the OIDC discovery document). No Keycloak-specific code is needed.
A minimal security configuration to protect all endpoints:
@Configuration@EnableWebSecuritypublic class SecurityConfig {
@Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/public/**").permitAll() .anyRequest().authenticated() ) .oauth2ResourceServer(oauth2 -> oauth2.jwt(Customizer.withDefaults())); return http.build(); }}Node with express-oauth2-jwt-bearer
Section titled “Node with express-oauth2-jwt-bearer”express-oauth2-jwt-bearer is Auth0’s MIT-licensed middleware that wraps jose for Express. Install it:
npm install express-oauth2-jwt-bearerimport { auth } from 'express-oauth2-jwt-bearer';import express from 'express';
const checkJwt = auth({ audience: 'my-app-backend', issuerBaseURL: 'http://localhost:8080/realms/my-app',});
const app = express();
app.get('/profile', checkJwt, (req, res) => { res.json({ sub: req.auth?.payload.sub });});The deprecated Keycloak adapters
Section titled “The deprecated Keycloak adapters”Keycloak used to ship per-framework adapters: keycloak-connect for Node, a Keycloak Spring Boot adapter, and others. These adapters are deprecated as of Keycloak 19 and will eventually be removed. New projects should use:
| Framework | Recommended library |
|---|---|
| Browser SPA | keycloak-js (official, still maintained) |
| Spring Boot backend | Spring Security OAuth2 Resource Server |
| Node/Express backend | jose or express-oauth2-jwt-bearer |
| Any other backend | Any JWT library that supports JWKS |