Adjusting registration SPI for Keycloak 23

Hey,

we have a custom Authentication SPI which extends the registration form with the ability to upload a pdf file which will be parsed and checked for specific values by the SPI.
This worked fine in Keycloak 22, during the upgrade (and the following tries to adjust the plugin) I encountered several problems.

First the org.keycloak.authentication.forms.RegistrationProfile class was deprecated in 23 (which I missed when reading the migration guide), so I drop-in replaced it with org.keycloak.authentication.forms.RegistrationUserCreation which seemed to work.

After the plugin was successfully loaded and could be added to the registration flow Keycloak threw HTTP 413 errors when trying to upload a pdf in the registration form. It turns out with Keycloak 23, a new Quarkus setting was introduced which limits the allowed size of a form. I thankfully could override this setting using quarkus.properties.

Now the (hopefully) last issue is that the login after registration does not work when the plugin is enabled.
I can add the plugin to the registration flow and it will work, users with wrong values in their pdf will be rejected and users with all values matching will be created.
Usually, after registration, the user should be logged in instantanly. This does work when the plugin is disabled in the flow but not when it is enabled.
The user is presented with Action expired. Please continue with login now.. Keycloak logs a LOGIN_ERROR event (after a successful REGISTER event):


The value in previous_user is the username of the user that was just registered.
From the Keycloak log:

2023-12-21 22:34:07,479 WARN  [org.keycloak.services] (executor-thread-26) KC-SERVICES0013: Failed authentication: org.keycloak.authentication.AuthenticationFlowException
        at org.keycloak.authentication.forms.RegistrationUserCreation.checkNotOtherUserAuthenticating(RegistrationUserCreation.java:159)
        at org.keycloak.authentication.forms.RegistrationUserCreation.success(RegistrationUserCreation.java:119)
        at org.keycloak.authentication.FormAuthenticationFlow.processAction(FormAuthenticationFlow.java:252)
        at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:133)
        at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:988)
        at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:362)
        at org.keycloak.services.resources.LoginActionsService.processRegistration(LoginActionsService.java:706)
        at org.keycloak.services.resources.LoginActionsService.registerRequest(LoginActionsService.java:762)
        at org.keycloak.services.resources.LoginActionsService.processRegister(LoginActionsService.java:740)
        at org.keycloak.services.resources.LoginActionsService$quarkusrestinvoker$processRegister_707378c0de357d574c0a2e1d6056afe7606ab5ff.invoke(Unknown Source)
        at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
        at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
        at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:145)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:576)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:840)
2023-12-21 22:34:07,483 WARN  [org.keycloak.events] (executor-thread-26) type=LOGIN_ERROR, realmId=b946c415-c820-45db-9348-5b647fc3e6ac, clientId=clientid, userId=null, ipAddress=192.168.56.1, error=generic_authentication_error, auth_method=openid-connect, auth_type=code, authentication_error_detail=different_user_authenticating, redirect_uri=http://127.0.0.1:8000/oidc/callback/, previous_user=sojfeosjf

This also happens when using a fresh browser, that can not be contaminated with login data from other users.
What could be the reason for this happening only when the plugin is enabled?
Please let me know if you need any other information to help :slight_smile:

Thanks for reading!
Levin

This problem can be resolved by overriding the success function of RegistrationUserCreation like this:

@Override
public void success(FormContext context) {

}

This seemingly was not needed when using the old RegistrationPage class.
It seems safe to do because it is done in the Terms and Conditions registration step as well.
Please correct me if I’m wrong.