Possible to return custom error messages when MFA is set up?

Hi there.

We extended Keycloak to be able to have users set up MFA. We implemented endpoints to create and remove MFA very similar to the suggestion in this comment (code can be found below)

@GET
@Path("your-end-point-to-fetch-the-qr")
@Produces({MediaType.APPLICATION_JSON})
public YourDtoWithSecretAndQr get2FASetup(@PathParam("username") final String username) {
    final RealmModel realm = this.session.getContext().getRealm();
    final UserModel user = this.session.users().getUserByUsername(username, realm);
    final String totpSecret = HmacOTP.generateSecret(20);
    final String totpSecretQrCode = TotpUtils.qrCode(totpSecret, realm, user);
    return new YourDtoWithSecretAndQr(totpSecret, totpSecretQrCode);
}

@POST
@Path("your-end-point-to-setup-2fa")
@Consumes("application/json")
public void setup2FA(@PathParam("username") final String username, final YourDtoWithData dto) {
    final RealmModel realm = this.session.getContext().getRealm();
    final UserModel user = this.session.users().getUserByUsername(username, realm);
    final OTPCredentialModel otpCredentialModel = OTPCredentialModel.createFromPolicy(realm, dto.getSecret(), dto.getDeviceName());
    CredentialHelper.createOTPCredential(this.session, realm, user, dto.getInitialCode(), otpCredentialModel);
}

Additionally, we created an Authenticator to return a custom error if users have MFA set up, but only submitted username and password as login credentials

override fun authenticate(context: AuthenticationFlowContext) {
  if (context.httpRequest.decodedFormParameters.getFirst("otp") == null) {
      context.failure(
          AuthenticationFlowError.INVALID_CREDENTIALS,
          Response.status(Status.UNAUTHORIZED)
              .entity("{\"error\": \"invalid_grant\",\"error_description\": \"MFA code required\"}")
              .type("application/json").build()
      )
      return
  }
  context.success()
}

My question is whether it is possible to return different error messages in Keycloak:

  • MFA inactive, username and password submitted → “Invalid user credentials”
  • MFA active, username, password and MFA code submitted, MFA code is invalid → “MFA is invalid”

Hi @lisa-tw ,

Would you mind sharing the full code for your SPI?

Thanks.