I need help for customizing the "reset-credentials" flow

Hello,

I am developing an extension to customize the “reset-credentials” flow, which is initiated when a user selects the “forgot password” option on the login page.
Specifically, I want the extension to send a verification email instead of a password reset email when the user’s email is unverified. In other words, I don’t want the user to be able to reset his password and login to the application until he is not verified.

Can you help me achieve this ?

I have already extended org.keycloak.authentication.authenticators.resetcred.ResetCredentialEmail
and successfully blocked the sending of the reset password email:

public class CustomResetCredentialEmail extends org.keycloak.authentication.authenticators.resetcred.ResetCredentialEmail {

    private static final Logger logger = Logger.getLogger(CustomResetCredentialEmail.class);

    @Override
    public void authenticate(AuthenticationFlowContext context) {
        UserModel user = context.getUser();
        logger.info("SemResetCredentialEmail.authenticate() >>> " + toString(user));

        if (user != null && !user.isEmailVerified()) {
            context.getEvent().user(user)
                    .detail(Details.USERNAME, user.getUsername())
                    .error("email_not_verified"); // Send a custom event to track the error
            // For security reasons we don't want to show the error message to the user, just continue the flow
            context.forkWithSuccessMessage(new FormMessage(Messages.EMAIL_SENT));
            return;
        }

        super.authenticate(context);
    }

}

However, I am unsure how to trigger the sending of the verification email using the Java APIs.

Any assistance would be greatly appreciated!

Thanks!

Question:

What do you expect to to gain from that change? The password reset and the verification probe the same thing: the user has access to the email account.

The user when resetting the password has access to the app but its email remains “unverified”.
See "reset credentials" flow should not work if email is unverified (or set the user's email as verified automatically) · Issue #37410 · keycloak/keycloak · GitHub
The extension would be a workaround for this.

Hello, I think one way to achieve this would be to override the “configuredFor()” method in your “CustomResetCredentialEmail” authenticator (this method returns true by default, but you could make it return true if email is verified and false otherwise).
In addition to this, use the “user configured” conditionnal authenticator in your reset credential flow. This will allow the subflow to run only if the “configuredFor()” method of your custom authenticator returns true.

The flow would look like :

  • step “Choose User” (REQUIRED)
  • subflow “reset pwd with email” (CONDITIONAL)
    • condition “user configured” (REQUIRED) → this is a built-in authenticator
    • step “custom reset credential” (REQUIRED) → your custom authenticator
    • … the rest of the reset credential flows here (which by default uses the “user configured” condition for the otp reset part. you can get inspiration from it)

Thank you for this insightful approach; it offers an alternative method to prevent the reset password email from being sent.

I’d like to explore a different approach: sending a verification email (rather than a password reset email) when a user is unverified. Do you have any suggestions on how to implement this in my custom “reset credentials” authenticator?

I wouldn’t implement this in an authenticator inside the reset credential flow. I would rely on the “verify email” built-in mecanism (Realm Settings > Login tab > Turn on the “Verify email” switch).