Neil Custer
Neil Custer

Reputation: 33

WSO2 Identity Server 5.7.0 - Password Policy Request for Minimum Password Age

I have researched at length all of the password policy options that have been added to the latest WSO2 Identity Server (5.7.0). While a big improvement over versions just a year old, my customer still is not satisfied over one issue. Using a password policy authenticator, looks like we can force a user to change their password every so many days, and using the now default policy options can enforce a password history requirement of any number to our liking. However, the history option could be overcome by a determined user simply changing his password the number of times required to age his password quickly in a single setting--unless there were a required "minimum password age" that would preclude them from doing so. All available options in History, Patterns, and Password Authenticator do not address this. This reference from Windows 10 security threat protection addresses the validity of this very issue: https://learn.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/minimum-password-age.

Is there a way I can set a minimum age in WSO2 IS now also? If not, should this not be included as a password policy in the history options?

Upvotes: 1

Views: 277

Answers (1)

senthalan
senthalan

Reputation: 2366

This feature is not currently available in the WSO2 IS product, But we can fulfil this requirement easily using the extensions available in the core user management system. The available password history feature has the history of the changed password dateTime, we can use those data to enforce this requirement.

  • Create a new Identity Connector to configure the minimum password age and Abstract Event Handler to enforce the validation during password change event.

    public class PasswordMinAgeValidationHandler extends AbstractEventHandler implements IdentityConnectorConfig {

    private static final Log log = LogFactory.getLog(PasswordMinAgeValidationHandler.class);
    
    @Override
    public void handleEvent(Event event) throws IdentityEventException {
    
        // Validate the password age with min age configured
    }
    
    @Override
    public String getName() {
        return "passwordMinAge";
    }
    
    @Override
    public String getFriendlyName() {
        return "Password Minimum Age";
    }
    
    @Override
    public String getCategory() {
        return "Password Policies";
    }
    
    @Override
    public Map<String, String> getPropertyNameMapping() {
        Map<String, String> nameMapping = new HashMap<>();
        nameMapping.put(PasswordMinAgeConstants.PM_MIN_AGE_ENABLE, "Enable Password Minimum Age Feature");
        nameMapping.put(PasswordMinAgeConstants.PW_MIN_AGE_COUNT, "Password Minimum Age (Days)");
        return nameMapping;
    }
    
    @Override
    public void init(InitConfig configuration) throws IdentityRuntimeException {
        super.init(configuration);
        IdentityPasswordMinAgeServiceDataHolder.getInstance().getBundleContext().registerService
                (IdentityConnectorConfig.class.getName(), this, null);
    }
    
    public Properties getDefaultPropertyValues(String tenantDomain) throws IdentityGovernanceException {
    
        Map<String, String> defaultProperties = new HashMap<>();
        defaultProperties.put(PasswordMinAgeConstants.PM_MIN_AGE_ENABLE, configs.getModuleProperties()
                .getProperty(PasswordMinAgeConstants.PM_MIN_AGE_ENABLE));
        defaultProperties.put(PasswordMinAgeConstants.PW_MIN_AGE_COUNT, configs.getModuleProperties()
                .getProperty(PasswordMinAgeConstants.PM_MIN_AGE_ENABLE));
        Properties properties = new Properties();
        properties.putAll(defaultProperties);
        return properties;
    }
    

    }

  • Make this class an OSGi bundle and register the PasswordMinAgeValidationHandler as AbstractEventHandler

    protected void activate(ComponentContext context) {
       try {
        BundleContext bundleContext = context.getBundleContext();
        IdentityPasswordMinAgeServiceDataHolder.getInstance().setBundleContext(bundleContext);
    
        PasswordMinAgeValidationHandler handler = new PasswordMinAgeValidationHandler();
        context.getBundleContext().registerService(AbstractEventHandler.class.getName(), handler, null);
    
    
    } catch (Exception e) {
        log.error("Error while activating identity governance password min age component.", e);
    }
    

    }

  • Deploy the jar in IS_HOME/repository/components/dropins
  • Add the following configurations in the IS_HOME/repository/conf/identity/identity-event.properties

    module.name.13=passwordMinAge passwordMinAge.subscription.1=PRE_UPDATE_CREDENTIAL passwordMinAge.subscription.2=PRE_UPDATE_CREDENTIAL_BY_ADMIN passwordMinAge.enable=false passwordMinAge.count=5

  • Restart the IS server

  • In the Resident Identity Provider configuration -> Password Policies, enable both Password History and Password Minimum Age features.

enter image description here

Here you can find the complete source code

Upvotes: 3

Related Questions