- Custom authenticator creates and logs in a guest user when the authorization request has guest=true; other requests get the login form - Scheduled task removes guests with no remaining sessions - Realm export with mancala-web PKCE client, guest role and guest-aware browser flow (verify profile disabled so guests are not asked for details) - Dockerfile building the extension into a Keycloak 26.7.5 image - Keycloak and Postgres in compose; nginx proxies auth.playmancala.app and rate limits the auth endpoint - Integration tests run the extension and realm in a Keycloak container
2.5 KiB
Mancala Keycloak
Keycloak is the only auth system for Mancala. Players can either log in with an account or play as a guest,
and both come back as normal Keycloak tokens from the mancala realm.
Guest login
extension/ adds a mancala-guest-authenticator to Keycloak. When an authorization request has guest=true,
it creates a new user named guest-xxxxxxxx, gives it the guest realm role and logs it in without showing a
form. Requests without the parameter fall through to the normal login form.
/realms/mancala/protocol/openid-connect/auth?client_id=mancala-web&response_type=code
&scope=openid%20offline_access&redirect_uri=...&code_challenge=...&code_challenge_method=S256
&guest=true
- Clients can tell guests apart by
"guest"in the access token'srealm_access.roles. - Guests should request
offline_accessso they keep their identity after the SSO session ends (offline sessions expire after 30 days without use). - A scheduled task deletes guests that are older than a day and have no session or offline session left.
Its timing can be changed with server options such as
KC_SPI_AUTHENTICATOR__MANCALA_GUEST_AUTHENTICATOR__CLEANUP_INTERVAL_SECONDS(default 3600),..._CLEANUP_MIN_AGE_SECONDS(default 86400) and..._CLEANUP_MAX_DELETES_PER_RUN(default 1000). - Each guest login creates a user, so the auth endpoint is rate limited per IP in
config/nginx.conf.
Realm
realm/mancala-realm.json holds the realm: the mancala-web public client (PKCE S256), the
browser with guest flow, the guest role, and the required actions with "Verify Profile" turned off so guests
are not asked for an email or a name.
Keycloak imports the file only if the realm does not exist yet. After changing it, apply the change in the admin console too, or delete the realm and restart Keycloak.
Running
cd apps
cat > .env <<EOF
KEYCLOAK_DB_PASSWORD=change-me
KEYCLOAK_ADMIN_PASSWORD=change-me
EOF
docker compose up -d --build keycloak
Keycloak is then at http://localhost:8080 and the admin console at http://localhost:8080/admin.
In production set KEYCLOAK_HOSTNAME=https://auth.playmancala.app; nginx proxies that host to port 8080.
Tests
cd apps/keycloak/extension
mvn test
The tests start Keycloak with the extension and the real realm file in a container, so they need Docker.
Upgrading Keycloak
The extension uses Keycloak's authenticator SPI, which Keycloak marks as internal. When upgrading, change the
version in extension/pom.xml and in Dockerfile together and run the tests.