keycloak redirect to update password url "login-actions/required-action"

Viewed 2375

I am building Identity management portal, using keycloak for authentication , i want to have one change password screen in this portal, when user click on that , it should redirect to keycloak theme update password screen ("http://host:port/auth/relams/<relam-name>/login-actions/required-action?execution=UPDATE_PASSWORD&client_id=test&tab_id=J4X7UdFi")

Can we achieve this in Keycloak after login?, this screen comes if we have Required Action as "UPDATE_PASSWORD" in Keyclaok UserRepresentation Object and before login if this action is there then keycloak itself redirects automatically to Update Password Screen ,

but can we give the Keycloak Update Password Screen directly to the user on UI after he logins.

1 Answers

We need to create RequiredActionProvider

package com.keycloak.password;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.jboss.logging.Logger;
import org.keycloak.authentication.RequiredActionContext;
import org.keycloak.authentication.RequiredActionProvider;
import org.keycloak.common.util.Time;
import org.keycloak.credential.CredentialModel;
import org.keycloak.credential.CredentialProvider;
import org.keycloak.credential.PasswordCredentialProvider;
import org.keycloak.credential.PasswordCredentialProviderFactory;
import org.keycloak.models.UserModel;

public class CustomUpdatePassword implements RequiredActionProvider {

    private static final String OPENID_CONNECT_PROTOCOL = "openid-connect";
    private static final String CLAIM_VALUE = "claim.value";
    private static final Logger LOG = Logger.getLogger(CustomUpdatePassword.class.getName());


    @Override
    public void evaluateTriggers(RequiredActionContext context) {

        try {
                //some custom logic add required_action
                    if (password.getCreatedDate() == null) {
                        context.getUser().addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
                    } else {
                        long timeElapsed = Time.toMillis(Time.currentTime()) - password.getCreatedDate();
                        long timeToExpire = TimeUnit.DAYS.toMillis(daysToExpirePassword);
                        if (timeElapsed > timeToExpire) {
                            context.getUser().addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);=
                        }
                    }
                
            }
        } catch (Exception e) {
            LOG.error(e.getMessage());
        }

    }

    @Override
    public void requiredActionChallenge(RequiredActionContext context) {
    }

    @Override
    public void processAction(RequiredActionContext context) {
    }

    @Override
    public void close() {

    }
}

And Factory class

package com.keycloak.password;

import org.keycloak.Config;
import org.keycloak.authentication.RequiredActionFactory;
import org.keycloak.authentication.RequiredActionProvider;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.KeycloakSessionFactory;

public class CustomUpdatePasswordFactory implements RequiredActionFactory {

    private static final CustomUpdatePassword SINGLETON = new CustomUpdatePassword();
  
    @Override
    public String getDisplayText() {
        return "Password Update";
    }

    @Override
    public RequiredActionProvider create(KeycloakSession keycloakSession) {
        return SINGLETON;
    }

    @Override
    public void init(Config.Scope scope) {

    }

    @Override
    public void postInit(KeycloakSessionFactory keycloakSessionFactory) {

    }

    @Override
    public void close() {

    }

    @Override
    public String getId() {
        return "Password Update";
    }
}

Then these class jars needs to deploy in the jboss folder

COPY --chown=jboss:root /target/<above_project_jar>-*.jar /opt/jboss/keycloak/providers/
Related