It is not really clear from your question, but since you have federated users from an external database, I assume you have implemented your custom UserStorageProvider
. You are also validating passwords against your external database. So, I assume you have also implemented CredentialInputValidator
interface. If you have not implemented CredentialInputUpdater
, I would assume what you are trying to achieve should work out of the box.
If you have implemented CredentialInputUpdater
, you could try to do the following:
Within you implementation of CredentialInputValidator.isvalid
first check if the user has a local password configured, e.g. like this
keycloakSession.userCredentialManager().isConfiguredLocally(realm, user, credentialInput.getType())
- If this is the case (returns
true
), simply have isValid
return false
. In this case Keycloak should use other CredentialInputValidator
s and check for the locally configured password.
- If this is not the case (returns
false
), do the password check against your external database. Iff the password is valid, silently migrate the password to Keycloak's local credential store. This could look something similar to this:
CredentialProvider passwordProvider = keycloakSession.getProvider(CredentialProvider.class, PasswordCredentialProviderFactory.PROVIDER_ID);
if (passwordProvider instanceof CredentialInputUpdater) {
((CredentialInputUpdater) passwordProvider).updateCredential(realm, user, credentialInput);
}
Within CredentialInputUpdater.updateCredential
make sure to update the local store in addition to the password in your database.
Now your user's passwords will be stored in Keycloak's local database / credential store and the built in password reset functionality should work as expected.