Skip to content

Framework Adapters

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-app

Spring 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
@EnableWebSecurity
public 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();
}
}

express-oauth2-jwt-bearer is Auth0’s MIT-licensed middleware that wraps jose for Express. Install it:

Terminal window
npm install express-oauth2-jwt-bearer
import { 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 });
});

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:

FrameworkRecommended library
Browser SPAkeycloak-js (official, still maintained)
Spring Boot backendSpring Security OAuth2 Resource Server
Node/Express backendjose or express-oauth2-jwt-bearer
Any other backendAny JWT library that supports JWKS
What does the Spring Security issuer-uri property tell Spring Boot?
How does Spring Security discover the JWKS URL from the issuer-uri?
Why are the old per-framework Keycloak adapters (keycloak-connect, etc.) not recommended?
Which keycloak-js feature is still the recommended choice for browser SPAs?