Passport strategy for authenticating with Keycloak using the OAuth2/OIDC API.
This module lets you authenticate using Keycloak in your Node.js applications. By plugging into Passport, Keycloak authentication can be easily and unobtrusively integrated into any application or framework that supports Connect-style middleware, including Express.
- Why I Did This
- What’s New in This Fork?
- Install
- Usage
- Understanding PKCE
- How to Get Roles
- Development
- Additional Information
- License
The original passport-keycloak wasn’t up to date. I modernized it with improved PKCE support, standalone client examples, and TypeScript support. Check out my blog for tutorials: blog.brakmic.com.
- TypeScript Only: The project is now TypeScript-based, with no JavaScript code.
- PKCE Support: Full Proof Key for Code Exchange (PKCE) implementation for public clients.
- Standalone Public Client: A single self-contained example demonstrating PKCE.
- Keycloak via Docker Compose: Simplified container-based setup.
pnpm install passport-keycloak-oauth2-oidc-portable
Configure your Keycloak realm and client to support the required OAuth2 flow. Ensure:
- For a public client:
- The
Access Type
is set topublic
. - No client secret is required.
- The
- For a confidential client:
- The
Access Type
is set toconfidential
. - The client secret is required.
- The
- The
Redirect URI
matches your application's callback endpoint.
import passport from "passport";
import KeycloakStrategy from "passport-keycloak-oauth2-oidc-portable";
passport.use(
new KeycloakStrategy(
{
clientID: "public-client-id",
realm: "MyRealm",
authServerURL: "http://localhost:8080",
callbackURL: "http://localhost:3000/callback",
publicClient: true, // Public client does not use client secret
pkce: true, // Enable PKCE for public clients
},
(accessToken, refreshToken, profile, done) => {
console.log("Authenticated user:", profile);
done(null, profile);
}
)
);
import passport from "passport";
import KeycloakStrategy from "passport-keycloak-oauth2-oidc-portable";
passport.use(
new KeycloakStrategy(
{
clientID: "confidential-client-id",
realm: "MyRealm",
authServerURL: "http://localhost:8080",
callbackURL: "http://localhost:3000/callback",
clientSecret: "your-client-secret", // Required for confidential clients
publicClient: false, // Set to false for confidential clients
},
(accessToken, refreshToken, profile, done) => {
console.log("Authenticated user:", profile);
done(null, profile);
}
)
);
The standalone public client demonstrates PKCE without relying on external services. It directly interacts with Keycloak for authentication.
-
Run the Standalone Public Client:
pnpm start:public-client --authServerUrl http://keycloak:8080 --client test-client --use-pkce
-
Output:
- The application will print the following:
Public Client running on http://localhost:3002 Using configuration: Auth Server URL: http://keycloak:8080 Realm: TestRealm Client ID: test-client Callback URL: http://localhost:3002/auth/keycloak/callback PKCE Enabled: true To start the authentication process, open the following URL in your browser: http://localhost:3002/auth/keycloak
- The application will print the following:
-
Visit the URL:
- Open
http://localhost:3002/auth/keycloak
in your browser to initiate the PKCE-based login.
- Open
-
Key Features:
- Completes the PKCE flow.
- Retrieves and logs access and ID tokens upon successful authentication.
Integrate passport.authenticate()
middleware in your routes. Use the example above for reference.
-
Start Keycloak (Docker Compose):
sudo docker compose -f test/bootstrap/docker-compose.test.yml up -d
-
Run the Standalone Client:
pnpm start:public-client --authServerUrl http://keycloak:8080 --client test-client --use-pkce