contabo / keycloak-spi-browser-session-api

A Keycloak SPI to start a browser session from a valid JWT
Apache License 2.0
16 stars 3 forks source link
keycloak single-sign-on spi sso

keycloak-spi-browser-session-api

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.

Usage

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.

API

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

Deployment

  1. Build with mvn clean package
  2. Copy resulting artifact keycloak-spi-browser-session-api-1.0.jar to the deployments folder of Keycloak

Configuration

There is no real configuration for the SPI itself. It relies on parameters of the SPI API call and Keycloak settings.

How to test locally?

Start Keycloak with PostgreSQL as the IDM Provider, a start-app and dest-app.

docker-compose up

The 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:

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.jar

Run 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.html

And please don't forget to reload http://localhost:5082

License

APACHE LICENSE, VERSION 2.0