javaauthenticationvalidationkeycloakregistration

Keycloak Custom Registration Flow Fails with "KC-SERVICES0013: Failed authentication: java.lang.NullPointerException" Error


I am following this guide and trying to create my custom registration flow in Keycloak using two forms and custom templates. Below I am providing the code of the authenticator factory for the first form. The second form uses the same code with the only changes that taking place are the PROVIDER_ID, getDisplayType() method and the return type of the render() method which is form.createForm("register2.ftl");. The Keycloak version I am using is 24.0.1.

I have:

public class FirstCustomFormAuthenticatorFactory implements FormAuthenticatorFactory, FormAuthenticator  {

    private static final String PROVIDER_ID = "register-form1";
    private static final AuthenticationExecutionModel.Requirement[] REQUIREMENT_CHOICES = {
            AuthenticationExecutionModel.Requirement.REQUIRED
    };

    @Override
    public String getDisplayType() {
        return "Registration Form 1";
    }

    @Override
    public String getReferenceCategory() {
        return "";
    }

    @Override
    public boolean isConfigurable() {
        return false;
    }

    @Override
    public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
        return REQUIREMENT_CHOICES;
    }

    @Override
    public boolean isUserSetupAllowed() {
        return false;
    }

    @Override
    public String getHelpText() {
        return "";
    }

    @Override
    public List<ProviderConfigProperty> getConfigProperties() {
        return List.of();
    }

    @Override
    public FormAuthenticator create(KeycloakSession keycloakSession) {
        return this;
    }

    @Override
    public void init(Config.Scope scope) {

    }

    @Override
    public void postInit(KeycloakSessionFactory keycloakSessionFactory) {

    }

    @Override
    public void close() {

    }

    @Override
    public String getId() {
        return PROVIDER_ID;
    }

    @Override
    public Response render(FormContext context, LoginFormsProvider form) {
        RegisterBean rb = new RegisterBean(new MultivaluedHashMap<>(), context.getSession());
        form.setAttribute("register", rb);
        return form.createForm("register.ftl");
    }
}

Keycloak server starts without any errors. Afterwards:

When submitting the form I am getting the next error:

KC-SERVICES0013: Failed authentication: java.lang.NullPointerException: Cannot invoke "org.keycloak.authentication.FormAuthenticator.render(org.keycloak.authentication.FormContext, org.keycloak.forms.login.LoginFormsProvider)" because "this.formAuthenticator" is null
        at org.keycloak.authentication.FormAuthenticationFlow.renderForm(FormAuthenticationFlow.java:307)
        at org.keycloak.authentication.FormAuthenticationFlow.processFlow(FormAuthenticationFlow.java:285)
        at org.keycloak.authentication.DefaultAuthenticationFlow.processSingleFlowExecutionModel(DefaultAuthenticationFlow.java:377)
        at org.keycloak.authentication.DefaultAuthenticationFlow.processFlow(DefaultAuthenticationFlow.java:246)
        at org.keycloak.authentication.DefaultAuthenticationFlow.processAction(DefaultAuthenticationFlow.java:133)
        at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:987)
        at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:364)
        at org.keycloak.services.resources.LoginActionsService.processRegistration(LoginActionsService.java:724)
        at org.keycloak.services.resources.LoginActionsService.registerRequest(LoginActionsService.java:780)
        at org.keycloak.services.resources.LoginActionsService.processRegister(LoginActionsService.java:758)
        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:147)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$14.runWith(VertxCoreRecorder.java:582)
        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:857)

I am not entirely sure what's causing the issue, as seen in my logs. Do you have any suggestions aa what I am doing wrong?


Solution

  • I managed to fix my issue. For some reason the configuration properties that had to be set in my first registration form where not applied correctly. As soon as logged in the admin console, I had to do to my realm and then in the Authentication tab. I had to select my custom registration flow and go to settings of my first step.