2

Is it possible to manage the password by keycloak with federated users? I have users federated from external database and currently also the password is being checked from the external database.

Is there a possibility to register a password in keycloak for the user just after that user is created in the external database and then federated to keycloak?

My motivation is having the built in password reset functionality of keycloak not building extra SPI code for this on federated users.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
simonC
  • 4,101
  • 10
  • 50
  • 78

2 Answers2

4

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 CredentialInputValidators 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.

sventorben
  • 1,597
  • 4
  • 17
  • yes I have UserStorageProvider implemented .... your answer look interesting, I have implemented only CredentialInputValidator, as I wanted the users being readonly .. the only exception to this rule is the passward. Currently If I try to change the passward I receive .... Uncaught server error: org.keycloak.storage.ReadOnlyException: user is read only for this update, ... your solution looks great ... if it works I will accept – simonC Jan 28 '22 at 12:48
  • I have UserStorageProvider and I am trying to check this condition -- keycloakSession.userCredentialManager().isConfiguredLocally(realm, user, credentialInput.getType()) but it always gives blank value. I am using Keycloak 20. Any clue? – Sanjay Prajapati Dec 15 '22 at 20:12
1

Is there a possibility to register a passward in keycloak for the user just after the user is created in external database and then federated to keycloak?

From the Keycloak Documentation itself:

By default, Keycloak will import users from LDAP into the local Keycloak user database. This copy of the user is either synchronized on demand, or through a periodic background task. The single exception to this is the synchronization of passwords. Passwords are never imported. Their validation is always delegated to the LDAP server. The benefits of this approach is that all Keycloak features will work as any extra per-user data that is needed can be stored locally. The downside of this approach is that each time that a specific user is queried for the first time, a corresponding Keycloak database insert is performed.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117