The goal of this SPI (Service Provider Interface) for Keycloak is to create a browser session by setting all relevant cookies out of a valid JWT (Json Web Token).
Useful to provide SSO (Single Sign On) capabilities for legacy web application to a new web application being authenticated by Keycloak.
Important to note is that this SPI expects the legacy web application to be able to access a valid JWT. This might occur if you need to introduce new features in legacy web applications.
Prerequisite is a valid JWT (access token) obtained from your Keycloak IDM.
With that valid JWT you may invoke within a browser the API provided by this SPI. E.g. with the following example JS code:
// config
var providerUrl = "http://localhost:5080";
var realm = "master";
var targetClientForNewSession = "application";
var jwt = "eyJhbGciOiJSUzI1NiIs.....";
// invocation
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", `${providerUrl}/auth/realms/${realm}/browser-session/init?publicClient=${targetClientForNewSession}`, false);
xmlHttp.withCredentials = true;
xmlHttp.setRequestHeader("Authorization", "Bearer " + jwt);
xmlHttp.send(null);
return xmlHttp.responseText;This will create a new user session for the provided client and set the Keycloak cookies so that after loading / redirecting to the URL of the application secured by Keycloak no prompt to login will appear.
It contains of one single API request:
| HTTP Method | Path | Request Header | Description |
|---|---|---|---|
| GET | baseUrl/auth/realms/realm/browser-session/init?publicClient=targetClientName |
Ensure Authorization: Bearer with the JWT |
baseUrl: URL to Keycloak e.g. https://your.keycloak.example.org realm: realm to be used e.g. master targetClientName: public client (defined in Keycloak) for which to start the browser session |
- Build with
mvn clean package - Copy resulting artifact
keycloak-spi-browser-session-api-1.0.jarto thedeploymentsfolder of Keycloak
There is no real configuration for the SPI itself. It relies on parameters of the SPI API call and Keycloak settings.
- As
userthe one identified by the JWT will be used - The
realmneeds to be passed as path element in the browser-session API URL, see example - The GET parameter
publicClientspecifies the public client to be used for new session, see example - For CORS the Web Origins settings from the
publicClientin Keycloak are used. Please note that*should be avoided in production environments.
Start Keycloak with PostgreSQL as the IDM Provider, a start-app and dest-app.
docker-compose upThe start-app is the starting point e.g. an application where a user is already logged in and has a valid JWT. Please open http://localhost:5082. For sake of simplicity no authentication takes place here.
The dest-app is just a demo website secured with keycloak.js.
The goal is to initiate a browser session from start-app only having a valid JWT to dest-app.
Please configure Keycloak as follows:
- login to Keycloak via http://localhost/ (
user/bitnami) - create two clients
dest-appwith access typepublicand Web Originhttp://localhost:5082and/or*privatewith access typeconfidential
- create one user
testuserwith passwordTest123!
Build and deploy it
mvn clean package && docker cp target/keycloak-spi-browser-session-api-1.0.jar keycloak-spi-browser-session-api-keycloak-1:/opt/bitnami/keycloak/standalone/deployments/keycloak-spi-browser-session-api-1.0.jarRun the test by generating a new access token and placing it into the demo/start-app/index.html. This is only for demo purposes.
CLIENT_ID=private
# ... please change CLIENT_SECRET accordingly as it gets generated by Keycloak
CLIENT_SECRET=8b3576db-6492-4238-aa60-d7c71a9663f7
API_USER=testuser
API_PASSWORD='Test123!'
ACCESS_TOKEN=$(curl -s -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" --data-urlencode "username=$API_USER" --data-urlencode "password=$API_PASSWORD" -d 'grant_type=password' 'http://localhost:5080/auth/realms/master/protocol/openid-connect/token' | jq -r '.access_token')
sed -i -E 's#var jwt = ".*$#var jwt = "'"$ACCESS_TOKEN"'";#' demo/start-app/index.htmlAnd please don't forget to reload http://localhost:5082
APACHE LICENSE, VERSION 2.0