Hi all,
After hours of digging, I found a way, at least, to check OTP code as a rest endpoint that I can use to validate the code in web application. Summary:
2) Relevant piece of code:
@GET
@Produces("text/plain; charset=utf-8")
public String check(@QueryParam("otp") String otp) {
LOGGER.info("Calling using otp={}", otp);
if (otp == null || otp.trim().length() != 6) {
return "NOK";
}
final RealmModel realm = session.getContext().getRealm();
AuthenticationManager.AuthResult authResult = new
AppAuthManager().authenticateIdentityCookie(
session, realm);
if (authResult == null) {
LOGGER.info("No authenticatedUser");
return "NOK";
}
UserModel authenticatedUser = authResult.getUser();
if (authenticatedUser == null) {
LOGGER.info("No authenticatedUser");
return "NOK";
}
final Optional<CredentialProvider<?>> cp = getCredentialProvider(session);
if (!cp.isPresent()) {
LOGGER.info("No credentialProvider");
return "NOK";
}
String credentialId = cp.get().getDefaultCredential(session, realm, authenticatedUser).getId();
boolean valid = ((CredentialInputValidator) cp.get()).isValid(realm, authenticatedUser,
new UserCredentialModel(credentialId, OTPCredentialModel.TYPE, otp));
return valid ? "OK" : "NOK";
}
private static Optional<CredentialProvider<?>> getCredentialProvider(KeycloakSession session) {
CredentialProvider<?> cp = session.getProvider(CredentialProvider.class, "keycloak-otp");
if (cp instanceof CredentialInputValidator) {
return Optional.of(cp);
}
return Optional.empty();
}
3) Deploy it to keycloak onto deployments folder.
Notes: It is very hacky from my perspective because I have to use classes from
keycloak-services to make it work. As I could not be able to deploy as a WAR because it does not work, I copy&paste&remove unnecesary code from classes to make it work. The deployment is a simple jar. Some Keycloak expert/advance user maybe know a better way or how to encapsulate it in a policy.
Hope it helps others that need to have some endpoint to validate OTP code. Ideally it should be a policy but at least this is a first version.
Juan