Okay, I figured out a way to do this without modifying the standard standalone keycloak distribution - there are pretty straightforward ways to modify the code of the keycloak deployment if you're willing to modify the keycloak source. I am new with Wildfly/Undertow so if any of this seems wrong or there's an easier way that more experienced folks know of please chime in.
1. Implement your ThreadSetupHandler
2. Implement an Undertow ServletExtension that adds the ThreadSetupHandler you implemented to the Deployment.
3. Package that in a jar with the standard ServiceLoader entry at META-INF/services/io.undertow.servlet.ServletExtension containing the name of the class implementing that interface
4. Deploy this as a module to $JBOSS_HOME/modules/. Make sure that your module.xml has a dependency on io.undertow.servlet. e.g.
<?xml version='1.0' encoding='utf-8'?>
<module xmlns='urn:jboss:module:1.1' name='
my.module.id'>
<resources>
<resource-root path='my.jar' />
</resources>
<dependencies>
<module name='org.jboss.logging' />
<module name='io.undertow.core' />
<module name='io.undertow.servlet' />
</dependencies>
</module>
5. Add this module to the server's global modules. This can be accomplished with the following cli snippet:
/subsystem=ee:list-add(name=global-modules, value={name=
my.module.id, services=true})
Now, when undertow starts up the servlet for keycloak, it will apply the servlet extension.
——
This part is for future folks trying to find a solution to the problem I had.
I wanted to put MDC values into keycloak server logs based on the incoming http request. There’s almost no discussion of people doing this with keycloak recently that I could find, and all I could find was to simply use a filter. The problem is that undertow passes the request/exchange to a separate worker pool, so keycloak is handling the request on a different thread than what your filter was running on. Since MDC is thread-local, this doesn't work as an approach to adding annotations to the keycloak logs. However, Undertow allows thread setup actions that are run before it runs servlet code but after passing the exchange to the worker thread where you can initialize thread locals.
Hope this helps someone.