KEYCLOAK - Setting a fixed issuer value
February 27, 2024
Keycloak derieves the issuer
value, used in the openid-configuration
document and in generated tokens, from the hostname settings of the server.
This is not wrong and a valid decision made by the team some time ago.
While one is not forced to do so, it’s totally ok to use the hostname as a valid issuer
value.
Sometimes, this comes to a downside and you need or want to set a fixed issuer
value in your Keyccloak server.
E.g. when your realm is available through different hostnames, for whatever reason.
But setting a fixed or custom value is not possible by default, as the responsible method to create the issuer
value, is a static method in the org.keycloak.services.Urls
utility class.
So, that’s also a… well, decision.
I had the challenge to solve exactly this - setting a custom and fixed issuer
value for a realm, no matter how (through which hostname) it is accessed.
After some fiddling around, I found a solution with some - some may say “dirty” hack - bytecode modification and overriding the respective method at server startup with my own logic to return the desired issuer
value.
Use bytecode modification only if there's no other way, at your own risk and only if you know what you are doing!!!
After all, this was easier as thought - Keycloak already uses ByteBuddy
for internal bytecode modification, so I “just” had to add the ByteBuddy Agent, so that I’m able to replace methods during runtime.
I implemented this with the help of my custom Initializer SPI, which allows me to do some operations and modifications in Keycloak only on startup, without the need to “misuse” one of the regular SPIs.
My IssuerInitializerProvider
reads the config, if there is a setting for the issuer
in the init()
method, then, during postInit()
I’m replacing the default Urls.realmIssuer()
static method with my custom implementation, see below.
Works like a charm and has minimal to no drawbacks during runtime, as only during startup the bytecode modification is done, nothing else during runtime!
Yes, bytecode modification can be dangerous, so always be sure what you do, don’t use it inflationary!
public static String realmIssuer(URI baseUri, String realmName) {
try {
baseUri = new URI(issuerBaseUri); // <-- set issuerBaseUri through configuration
} catch (URISyntaxException | NullPointerException ignored) {
}
return Urls.realmBase(baseUri).path("{realm}").build(realmName).toString();
}
It's an often-seen anti-pattern: Never misuse existing SPIs for something else, they are all there for a purpose. Create your own SPI, it's easy! See e.g. my above mentioned Initializer SPI
Du bist auf der Suche nach Keycloak Beratung, Unterstützung, Workshops oder Trainings?
Nimm Kontakt mit mir auf!« KEYCLOAK - Flushing and clear Realm and User Caches via Admin REST API Keycloak DevDay 2025 Announcement and Call-for-Papers »