Account status verification - LDAP Decision Node

I have an authentication tree which is using an LDAP decision node. Currently, only the “active” users can be authenticated which is fine, however, I received a new requirement where we should support more statuses to be considered during authentication (let’s say “dormant”). It looks this component always checks the “active” status. Is there any way to set up additional statuses to be checked by this particular node?

AM version: 7.2.1

Hi,
This feature will be part of a future LDAP decision node, you can track its progress here: https://bugster.forgerock.org/jira/browse/OPENAM-13935

In the meanwhile, you can achieve the same behaviour using a scripted node that would query the LDAP account through an IDM LDAP connector using the scripted decision node API. An example of such a script is below, please note it can be modernized using the latest scripting API capabilities, to make the call to IDM easier to achieve, but would likely require you to ugrade to a more recent AM version (7.4 presumably):

(function () {
var fr = JavaImporter(
org.forgerock.openam.auth.node.api,
org.forgerock.http.protocol.Request,

);

with (fr) {
    var tenantFqdn = systemEnv.getProperty("esv.tenant.env.fqdn");
    var linkTypeName = "systemAdpocUser_managedAlpha_user";
    if (!tenantFqdn) {
        action = Action.goTo("error").build();
    }
    function getADAccountStatus(tenantFqdn, id, idmToken,linkTypeName) {

        var idmEndpoint = "https://"
            .concat(tenantFqdn)
            .concat("/openidm/sync?_action=getLinkedResources&resourceName=managed/alpha_user/")
            .concat(id);

        try {
            var request = new org.forgerock.http.protocol.Request();
            request.setMethod("POST");
            request.setUri(idmEndpoint);
            request.getHeaders().add("Content-Type", "application/json");
            request.getHeaders().add("Accept-API-Version", "resource=1.0");
            request.getHeaders().add("Authorization", "Bearer " + idmToken);

            var response = httpClient.send(request).get();
            var entries = JSON.parse(response.getEntity().getString());
            logger.error("###############################-SOR-entries: " + entries);
            var adEntry = entries.find(item => String(item.linkType) === linkTypeName);
            logger.error("###############################-SOR-adEntry: " + adEntry);
            var userAccountControl = String(adEntry.content.userAccountControl);
            logger.error("###############################-SOR-userAccountControl: " + userAccountControl);
            var pwdLastSet = String(adEntry.content.pwdLastSet);
            logger.error("###############################-SOR-pwdLastSet: " + pwdLastSet);

            sharedState.put("userAccountControl", userAccountControl);
            sharedState.put("pwdLastSet", pwdLastSet);
          
            if (userAccountControl === '514') {
            	logger.error("###############################-SOR-Account disabled");
                return 'disabled';
            } else if (userAccountControl === '512' && pwdLastSet > '0') {
            	logger.error("###############################-SOR-Account enabled");
                return 'enabled';
            } else if (userAccountControl === '512' && pwdLastSet === '0') {
            	logger.error("###############################-SOR-Account mustChange");
                return 'mustChange';
            } else {
                return 'other';
            }
        } catch (e) {
            logger.error("###############################-SOR-error: " + e);
            action = Action.goTo("error").build();
        }
    }
    var userStatus = getADAccountStatus(tenantFqdn, nodeState.get("_id").asString(), nodeState.get("idmAccessToken").asString(), linkTypeName);

    action = Action.goTo(userStatus).build();

}

}());

1 Like