Skip to main content

Keycloak SAML2 Setup

This guide explains how to set up Keycloak as a SAML2 Identity Provider (IdP) for local development with Artemis. The provided Keycloak configuration includes a preconfigured artemis realm with SAML2 client settings, attribute mappers, and test users.

Prerequisites​

  • Docker and Docker Compose installed on your machine
  • OpenSSL installed (for generating signing credentials)

Start Keycloak​

docker compose --env-file .env -f deployment/docker/saml-test.yml up -d

This starts Keycloak with the following configuration:

ServicePortDescription
Admin Console9080Keycloak admin UI
SAML Endpoint9080SAML2 protocol endpoint

Verify Keycloak is running by opening the admin console:

http://localhost:9080

Login with admin / admin.

Generate SAML2 Signing Credentials​

Spring Security requires signing credentials for the SAML2 relying party registration, even if the IdP does not require signed authentication requests.

Generate a self-signed certificate and private key. Write them to a directory outside your Artemis working tree, so a private key can never end up in a commit:

mkdir -p ~/.artemis/saml && cd ~/.artemis/saml

# Generate a self-signed certificate and RSA private key
openssl req -x509 -newkey rsa:2048 -keyout saml-key.pem -out saml-cert.crt -days 365 -nodes -subj "/CN=artemis"

# Convert the private key to PKCS#8 format (required by Spring Security)
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in saml-key.pem -out saml-key-pkcs8.pem

Find the absolute paths to the generated files (needed for the configuration):

# Unix/macOS
realpath saml-key-pkcs8.pem saml-cert.crt

Configure Artemis​

Enable the SAML2 module feature​

SAML2 is now controlled by the artemis.user-management.saml2.enabled module-feature flag (the legacy saml2 Spring profile has been removed). Add it to your application-local.yml and ensure your run configuration uses the standard Artemis profile set:

SPRING_PROFILES_ACTIVE=artemis,scheduling,core,dev,local
artemis:
user-management:
saml2:
enabled: true

Add SAML2 Configuration to application-local.yml​

Add the following to src/main/resources/config/application-local.yml.

When accessing Artemis at http://localhost:8080 (direct Spring Boot, or ./gradlew bootRun):

spring:
security:
saml2:
relyingparty:
registration:
keycloak:
entity-id: artemis
signing:
credentials:
- private-key-location: file:<ABSOLUTE_PATH>/saml-key-pkcs8.pem
certificate-location: file:<ABSOLUTE_PATH>/saml-cert.crt
assertingparty:
metadata-uri: http://localhost:9080/realms/artemis/protocol/saml/descriptor

saml2:
username-pattern: 'saml2-{first_name}_{last_name}'
first-name-pattern: '{first_name}'
last-name-pattern: '{last_name}'
email-pattern: '{email}'
registration-number-pattern: '{uid}'
lang-key-pattern: 'en'
identity-providers:
- metadata: http://localhost:9080/realms/artemis/protocol/saml/descriptor
registration-id: keycloak
entity-id: artemis

info.saml2:
buttonLabel: 'SAML2 Login'

Replace <ABSOLUTE_PATH> with the actual absolute path from the realpath call under Generate SAML2 Signing Credentials.

Angular Dev Server (port 9000)​

When using pnpm start (Angular dev server on port 9000), the SAML2 paths must be proxied to the Spring Boot server. The proxy configuration in config/client/proxy.conf.mjs must include /saml2/ and /login/saml2/ — these are already configured in the project.

The Keycloak realm also needs http://localhost:9000/login/saml2/sso/keycloak as an allowed redirect URI. This is preconfigured in the provided artemis-realm.json.

Containerized Artemis Setup​

When running Artemis as a Docker container, combine the SAML2 compose file with your Artemis compose file:

docker compose --env-file .env -f deployment/docker/artemis-dev-mysql.yml -f deployment/docker/saml-test.yml up

Then uncomment the artemis-app service section in deployment/docker/saml-test.yml to mount the SAML2 configuration into the Artemis container:

artemis-app:
volumes:
- ./saml-test/application-saml2.yml:/opt/artemis/config/application-saml2.yml

You also need to set ARTEMIS_USER_MANAGEMENT_SAML2_ENABLED=true (or the equivalent artemis.user-management.saml2.enabled: true YAML key) in your Artemis compose configuration.

Test the SAML2 Login​

  1. Start Keycloak: docker compose --env-file .env -f deployment/docker/saml-test.yml up -d
  2. Start Artemis with artemis.user-management.saml2.enabled=true and the configuration above
  3. Open Artemis in your browser
  4. Click SAML2 Login on the login page
  5. Authenticate with a test user:
    • saml2user1 / password
    • saml2user2 / password
  6. You should be redirected back to Artemis and logged in

Keycloak Admin Console​

The Keycloak admin console is available at http://localhost:9080 (credentials: admin / admin).

The preconfigured artemis realm includes:

ItemDetails
SAML ClientClient ID: artemis
Test Userssaml2user1 / password, saml2user2 / password
Attribute Mappersfirst_name, last_name, email, uid
Allowed Redirectshttp://localhost:8080/... and http://localhost:9000/...

Troubleshooting​

"Invalid Request" on Keycloak Login Page​

This usually means the SAML entity ID sent by Artemis does not match the client ID in Keycloak.

Fix: Ensure entity-id: artemis is set in the Spring Security registration config (under spring.security.saml2.relyingparty.registration.keycloak).

"Invalid redirect uri" on Keycloak Login Page​

Keycloak is rejecting the Assertion Consumer Service (ACS) URL because it is not in the allowed redirect URIs list.

Fix: The preconfigured realm allows both localhost:8080 and localhost:9000. If you changed the port, update the redirect URIs in the Keycloak admin console: Realm: artemis → Clients → artemis → Valid Redirect URIs.

"Signing credentials must not be empty" on Artemis Startup​

Spring Security requires signing credentials for the SAML2 relying party registration.

Fix: Generate the signing credentials as described in Generate SAML2 Signing Credentials and add the signing.credentials section to your application-local.yml.

"Private key location does not exist" on Artemis Startup​

The file path in private-key-location is incorrect or the file does not exist.

Fix: Use realpath saml-key-pkcs8.pem to find the correct absolute path. The path must be prefixed with file: (e.g., file:/Users/you/project/saml-key-pkcs8.pem).

"spring.profiles.active is invalid in a profile-specific resource" on Startup​

You have spring.profiles.active set inside application-local.yml, which Spring Boot does not allow in profile-specific files.

Fix: Remove spring.profiles.active from application-local.yml and set the profiles via your IntelliJ run configuration or the SPRING_PROFILES_ACTIVE environment variable instead.

SAML2 Login Button Clicks but Nothing Happens (401)​

The browser stays on the Artemis login page after clicking "SAML2 Login".

Fix (Angular dev server): Ensure the proxy config in config/client/proxy.conf.mjs includes /saml2/ and /login/saml2/. Restart pnpm start after changes.

Container Logs​

Check Keycloak logs for errors:

docker compose --env-file .env -f deployment/docker/saml-test.yml logs keycloak

Resetting the Keycloak Realm​

To completely reset the Keycloak configuration and re-import the realm:

docker compose --env-file .env -f deployment/docker/saml-test.yml down -v
docker compose --env-file .env -f deployment/docker/saml-test.yml up -d
Search documentation