Order of Keycloak authenicators and required actions

Need some help understanding authenticators and required actins. Shouldn’t Keycloak display a required action for an authenticator before moving to another authenticator in my flow? Let’s say I have authenticator A and authenticator B. They are in the flow after the password form. All are set to required. Here’s what happens:

Authenticator A returns false for isConfiguredFor(). Keycloak then calls A.getRequiredActions() followed by A.setRequiredActions(). That makes sense.

Next the A.authenticate() is called. Shouldn’t that not be called yet because the required action hasn’t executed? I am calling context.success() in A.authenticate() because I there is nothing to authenticate. A is really just a placeholder to cause the required action to occur.

The next thing that happens is authenticator B is called. B.authenticate calls context.challenge() and then B.action is called and if the user enters the right code, the authentication completes.

Now, after authenticator B is complete, the required action from A is finally displayed. How do I get the required action displayed in the right place?

I have run and built the “secret question” example and based my code on that. It seems to work as I expected - the action to set up the question is displayed and authenticate is never called.

Here’s my flow as described in this question. I intend to add another auth check into the flow later on the same level as SMS. Either SMS or OTP will be presented to the user based on his or her choice from the “Select 2FA Authentication Type” authenticator.

Did you ever find an answer to this? I’m also having trouble following the logic of the flow executions. I have a custom SMS/Email 2fa implementation working and after I introduce the built-in OTP execution, it will always default to that and never call the configuredFor method in my custom execution.

I put my custom authenticator before the built in otp one. I also have another authenticator before the sms one that asks the user if they want to use SMS or OTP. Both of them are marked as required. If the user is not using SMS, they simply return success and the flow continues. I put the built in OTP authenticator in a conditional subflow. I also wrote a conditional authenticator to put in the same subflow as the otp one. if it returns false, then the subflow is not run, thereby skipping the otp authenticator. This is from memory. I will be glad to pass on some more details if it helps.

Thank you for replying. I was able to get this to work in much the same way you did. Splitting the two executions into their own Alternative flows and adding the conditional - user configured execution alongside both executions. I also ended up customizing the built-in OTP in order to implement our own remember device logic.

Thanks again for the quick reply and advice!

Hey @ionyx0, I found your answer when looking for keycloak otp plugins that support remembering a device. Would you mind sharing your implementation? We’re trying to implement it ourselves and I can only find examples of custom sms or email otp. Not sure how to customize the built-in otp.

It’s been a while since I implemented this (and to be honest, we aren’t using OTP in our app right now). Hopefully, I can point you in the right direction.

In order to build a custom OTP authenticator, I extended the following classes in my plugin:
Factory: OTPFormAuthenticatorFactory (also implement ServerInfoAwareProviderFactory)
Authenticator: OTPFormAuthenticator

Once you have those built, the config in Keycloak is much the same as the custom SMS/Email authenticator examples you found.

Let me know if I can help any further.