How to integrate Keycloak OIDC with Axelor 8.1+ when OidcClient is not registered and /ws/auth/providers returns 404?
I am attempting to enable OIDC login with Keycloak in Axelor 8.1.11, but the ‘Log in with Keycloak’ button does not appear, and the OidcClient is not registered in the startup logs. Additionally, the /ws/auth/providers endpoint returns a 404 error.
My current environment and configuration are as follows:
Environment:
- Axelor version: 8.1.11 (from
build.gradle) - Gradle plugin: 7.1.0
- Java: 11
- Keycloak: 26.x
- Auth framework: pac4j (bundled by Axelor)
application.properties configuration:
auth.provider.oidc.enabled=true
auth.provider.oidc.title=Log in with Keycloak
auth.provider.oidc.icon=key
auth.oidc.discovery.uri=http://localhost:8086/realms/my-realm/.well-known/openid-configuration
auth.oidc.client.id=myapp
auth.oidc.client.secret=*****
auth.oidc.callback.url=http://localhost:8080/myapp/callback
Observed Problems:
- OidcClient not registered: Startup logs only show
Indirect clients: [AxelorFormClient, AxelorIndirectBasicAuthClient], missingOidcClient/KeycloakOidcClient. /ws/auth/providersreturns 404: This endpoint is inaccessible.
What steps are required to successfully enable Keycloak OIDC with Axelor 8.1+, specifically regarding necessary modules, correct configuration, or compatible plugin/runtime combinations to resolve these issues?
Your Axelor Keycloak OIDC problem is almost always a configuration/classpath issue plus an edition limitation: Axelor registers pac4j OIDC clients only when properties are under an auth.provider./ws/auth/providers endpoint + SSO UI are provided only in the Enterprise edition. Remove the invalid flag, move your keys under an auth.provider.pac4j-oidc module is on the classpath (matching Axelor’s pac4j version), set the callback URL to exactly match Keycloak’s redirect URI, then restart and check the startup logs for the OidcClient registration.
Contents
- Axelor Keycloak OIDC Configuration
- Resolving OidcClient Not Registered
- Understanding
/ws/auth/providers404 (Enterprise vs Community) - Required Modules, dependencies and version compatibility
- Debugging checklist & common errors
- Sources
- Conclusion
Axelor Keycloak OIDC Configuration
Why your current file fails: Axelor auto-discovers and builds pac4j clients from application properties that begin with auth.provider.
- Heads-up:
auth.provider.oidc.enabled=trueis not a valid toggle in Axelor 8.x and its presence prevents the OIDC client from being registered (per the Axelor 8.0 security notes). See the official docs for details: Axelor 8.0 security guide. - The correct shape is auth.provider.
. . Use either a Keycloak-specific provider block (simpler) or declare the OIDC client class and use discovery.
Recommended property examples (pick one approach):
- Generic OIDC via discovery (recommended if you want a generic OIDC client)
# declare the pac4j client class and discovery URI
auth.provider.keycloak.client = org.pac4j.oidc.client.OidcClient
auth.provider.keycloak.discovery-uri = http://localhost:8086/realms/my-realm/.well-known/openid-configuration
auth.provider.keycloak.client-id = myapp
auth.provider.keycloak.secret = <secret>
auth.provider.keycloak.callback-url = http://localhost:8080/myapp/callback
auth.provider.keycloak.title = Log in with Keycloak
auth.provider.keycloak.icon = key
- Keycloak-specific (Axelor understands Keycloak shortcuts)
auth.provider.keycloak.client-id = myapp
auth.provider.keycloak.secret = <secret>
auth.provider.keycloak.realm = my-realm
auth.provider.keycloak.base-uri = http://localhost:8086
auth.provider.keycloak.callback-url = http://localhost:8080/myapp/callback
auth.provider.keycloak.title = Log in with Keycloak
auth.provider.keycloak.icon = key
Key points:
- Delete/comment out
auth.provider.oidc.enabled=true. That line prevents registration. - Use a provider name other than the literal “oidc” if you like (e.g., keycloak) — Axelor creates a client per unique auth.provider.
block. - The callback URL must exactly match what’s configured in Keycloak (no host/ip mismatch, no trailing-slash differences). See the GitHub issue about redirect/domain mismatches for an example: axelor/axelor-open-suite#4825.
Resolving OidcClient Not Registered
Step-by-step to fix “OidcClient not registered”:
- Remove the invalid flag
- Remove
auth.provider.oidc.enabled=truefrom application.properties.
- Move properties under auth.provider.
- Replace your
auth.oidc.*keys withauth.provider.keycloak.*(or another provider name) per examples above.
- Ensure
pac4j-oidcis present on the classpath
- For the Community distribution you may need to add the dependency manually (see next section).
- Make sure the pac4j-oidc version matches Axelor’s pac4j runtime to avoid runtime ClassCastExceptions.
- Restart Axelor and watch the startup logs
- Look for log lines showing pac4j clients being created/registered (the startup normally lists indirect clients). If you see
Indirect clients: [AxelorFormClient, AxelorIndirectBasicAuthClient, OidcClient]then registration succeeded. - If not, enable debug for the registration package (see Debugging section).
- Programmatic fallback (if you must)
- If you need to register a client programmatically (for Community edition customization or special setup), extend Axelor’s AuthPac4jModule and register an OidcClient in your module’s configure method. The Axelor source shows the AuthPac4jModule you extend: AuthPac4jModule.java. The pac4j docs explain how to create an OidcClient object: pac4j OpenID Connect docs.
Understanding /ws/auth/providers 404 (Enterprise vs Community)
Short answer: /ws/auth/providers and the full SSO login-button UI are part of Axelor’s Enterprise SSO features; they are not shipped in the Community edition. The Axelor 8.0 doc explicitly states the endpoint/UI are Enterprise-only and will return 404 in Community instances: Axelor 8.0 security guide.
Options when you hit 404:
- If you want the out-of-the-box SSO UI and providers REST endpoint, use the Axelor Enterprise edition. That will show the “Log in with Keycloak” button and populate
/ws/auth/providers. - If you stay on Community:
- You can still register an OidcClient (see previous section) and then implement your own login button/UI that redirects users to the pac4j authorization entrypoint. The REST endpoint and UI simply won’t be present by default.
- Or, build a small front module that exposes the login button and calls the available authentication endpoints.
See the user report of the exact problem and solutions discussed here: StackOverflow thread with the same symptoms.
Required Modules, dependencies and version compatibility
Must-haves
- pac4j OIDC module on the classpath:
org.pac4j:pac4j-oidc(match the pac4j major version Axelor uses). Example Gradle add (adjust version to match Axelor):
dependencies {
implementation 'org.pac4j:pac4j-oidc:5.7.0' // example — align with Axelor's pac4j version
}
- Java 11 is fine for pac4j v5.x (your environment Java 11 is OK).
Version compatibility caveats
- If your pac4j-oidc version differs from the pac4j core that Axelor loads, you may see ClassCastException or other runtime errors (see the pac4j/JEE example of version mismatch): https://stackoverflow.com/questions/75983757/oidc-for-jee-with-pac4j. To avoid that, inspect Axelor’s dependency list and use the same pac4j versions (
./gradlew dependenciesor check the distribution’s libs).
Keycloak side
- Configure the Keycloak client as a confidential client (if you use client secret) and set the Valid Redirect URI exactly to the callback URL you set in Axelor (
http://localhost:8080/myapp/callback). - Confirm the Keycloak discovery document is reachable:
curl http://localhost:8086/realms/my-realm/.well-known/openid-configuration— look for issuer, authorization_endpoint, token_endpoint, jwks_uri.
Debugging checklist & common errors
Quick checklist you can run now
- Remove
auth.provider.oidc.enabled=true. - Replace
auth.oidc.*withauth.provider.<your-name>.*using one of the examples above. - Ensure
pac4j-oidcjar present and version-compatible. - Restart Axelor and tail the logs. Search for client-registration messages or errors in the
com.axelor.auth.pac4jpackage. - Curl the discovery URL to ensure Keycloak serves the config and JWKS:
curl -sS http://localhost:8086/realms/my-realm/.well-known/openid-configuration | jq . - Confirm Keycloak client Redirect URI exactly matches your
callback-url(watch for domain vs IP redirection issues — example: issue #4825).
Common errors and fixes
- OidcClient still not listed: double-check keys are under
auth.provider.<name>.*. Enable debug logging for the Axelor auth pac4j package and re-check logs. If still nothing, you likely need to addpac4j-oidcto the classpath or register the client programmatically. - ClassCastException or NoSuchMethodError: pac4j version mismatch. Align pac4j-oidc version with Axelor’s pac4j core.
- BadJOSEException / JWT errors: check Keycloak token signature algorithm (usually RS256), verify jwks_uri is reachable, and ensure no proxy is rewriting hosts that break issuer/jwks retrieval.
/ws/auth/providersis 404: you’re likely on Community edition; upgrade to Enterprise for the REST endpoint and SSO UI, or add a custom UI endpoint.
Commands & checks
- Dependency tree:
./gradlew dependencies --configuration runtimeClasspath | grep pac4j -n - Check discovery document:
curl -v http://localhost:8086/realms/my-realm/.well-known/openid-configuration - Enable debug logs for the Axelor auth package (edit logging config to set
com.axelor.auth.pac4jto DEBUG) and watch registration details.
Sources
- Axelor 8.0 — Security (dev-guide)
- Axelor 7.4 — Security (dev-guide)
- StackOverflow: Trying to integrate Keycloak with Axelor 8 but can’t get button “Log in with Keycloak”
- pac4j OpenID Connect docs
- AuthPac4jModule (Axelor source)
- axelor/axelor-open-suite Issue #4825 — redirect / callback mismatch
- StackOverflow: OIDC for JEE with pac4j (dependency / ClassCastException example)
Conclusion
Short checklist to get your Axelor Keycloak OIDC working: delete the invalid enabled flag, move your OIDC keys under an auth.provider.pac4j-oidc is on the classpath with a matching version, set the callback URL exactly as registered in Keycloak, and then restart and confirm the OidcClient appears in the startup logs. Remember: /ws/auth/providers and the shipped SSO button are Enterprise features — if you’re on Community, either add a small custom UI/module or upgrade to Enterprise to see that endpoint and the login button out of the box.