Skip to main content

Keycloak OIDC Setup for Local Development

In production, Artemis signs users in through the university's OpenID Connect provider. To work on anything that touches that flow, you need a provider locally, and this setup gives you one: a Keycloak container that imports a ready-made artemis-oidc realm with 21 test accounts.

Step 1: Start Keycloak

Keycloak on its own needs no variables, because the compose file pins its version inline:

docker compose -f docker/oidc-test.yml up -d

Together with a database, pass --env-file .env, since those compose files take their image versions from it and have no fallbacks:

docker compose --env-file .env -f docker/artemis-dev-mysql.yml -f docker/oidc-test.yml up -d

You now have:

WhatWhere
Keycloak admin consolehttp://localhost:9080, sign in with admin / admin
Realmartemis-oidc
Discovery documenthttp://localhost:9080/realms/artemis-oidc/.well-known/openid-configuration

The realm is imported from docker/oidc-test/artemis-oidc-realm.json on every start, so anything you change in the admin console is gone when you recreate the container. Edit that file instead if you need a change to stick.

Step 2: Point Artemis at it

Copy docker/oidc-test/application-oidc-test.yml into your src/main/resources/config/application-local.yml. That file holds everything needed: the artemis.user-management.oidc.enabled flag, the claim mappings, and the client and provider blocks aimed at localhost:9080.

Then start Artemis with the oidc profile:

./gradlew bootRun --args='--spring.profiles.active=dev,artemis,localci,localvc,core,oidc,local'

An alternative that sidesteps the ordering question altogether: application-oidc.yml reads every endpoint from an environment variable (ARTEMIS_OIDC_ISSUER_URI, ARTEMIS_OIDC_AUTHORIZATION_URI and so on), and environment variables outrank profile files whatever their order. Setting those is a reasonable option if you switch between the local and the real provider often.

Step 3: Check the client proxy

If you run the client through the Angular dev server on port 9000, the login redirects have to reach the server through the proxy. proxy.conf.mjs already forwards them:

context: [
// ...
"/oauth2/",
"/login/oauth2/",
],
target: "http://localhost:8080",

Nothing to do here unless you have changed that file.

Step 4: Sign in

The realm imports one administrator and 20 test users. Every password equals the username, so artemis_test_user_7 signs in with artemis_test_user_7.

Keycloak accountKeycloak group
artemis_adminartemis-admins, artemis-instructors
artemis_test_user_1 to _5artemis-students
artemis_test_user_6 to _10artemis-tutors
artemis_test_user_11 to _15artemis-editors
artemis_test_user_16 to _20artemis-instructors

Troubleshooting

The browser goes to login.tum.de instead of my container. The local profile is not last in --spring.profiles.active, so application-oidc.yml and its production defaults won. Move local to the end, or set the ARTEMIS_OIDC_* environment variables.

Login succeeds, then Artemis fails with Communications link failure. Keycloak is up but the Artemis database is not. Start the database compose file and try again.

An account signs in but has the wrong role. Its roles come from the Artemis database, not from Keycloak. Check that the database was migrated with the e2e Liquibase context, which is what seeds artemis_test_user_1 to _20 and their authorities.

Keycloak is unreachable, or the container sits in Created. Read the container log with docker logs artemis-keycloak-oidc. A realm import that fails leaves the container in exactly that state, and the log names the offending part of the JSON.

My admin-console change disappeared. The realm is re-imported on every container start. Put the change in docker/oidc-test/artemis-oidc-realm.json and recreate the container.

Search documentation