Search code examples
passwordskeycloakfederation

keycloak managed password with federated users


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.


Solution

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