Is it possible to add a pre-registration step (using a Form Action) to the registration flow?

Hello all,

I have a requirement where I need to verify a potential user’s date of birth from an external system before allowing the user to create/register an account in Keycloak. I’m using the language “potential user” to communicate that at this point in the registration process for my app, the user hasn’t actually registered an account yet in Keycloak.

In order to satisfy this requirement, I’ve tried implementing the FormAction SPI. My buildPage method is used to extract the user’s UUID (from the external system) from a query parameter in the registration url (for example, &externalId=123). It then binds this UUID to a hidden field in the verify details form. Lastly, it renders the “Verify Details” template (freemarker template).

I’ve implemented the validate method to make a request to the external server, using the person’s UUID, to get their information, and compare the DOB they entered into the form with what was returned from the external server. If what they entered matches what was returned in the response, I want to forward them to the registration form to allow them to create an account.

I was able to implement the above as described, and I built the jar, then got the jar picked up by my Keycloak instance (running locally for now in a docker container). I was able to add this form action as part of the registration flow. I circled my custom step in red to visually show where I want it to happen in the registration process.

However, when I navigate to the registration page, my verify details step never seems to be invoked. Instead, I am shown the registration form for creating a new account. I don’t see any logs in the Keycloak server, despite setting the log level to debug. This step only seems to be invoked if I place it after the “Registration User Creation” step.

It’s worth noting that I originally had this “Verify Details” step being handled in a React app and not on the Keycloak server. But I was hoping I could make it part of the registration flow because it will simplify my app’s design, and also I’d ideally like to add the external UUID of the user (from the other system) as a claim in the ID token that gets sent back to the front end. Therefore, I was hoping that I could read it as a query param, verify details on Keycloak, then pass it into the registration form, and ultimately have it end up as part of a user’s attributes.