Scripted Decision Node API Functionality

In addition to the functionality provided by "Accessing HTTP Services" and "Debug Logging", scripted decision nodes can access request headers, the authentication session's shared state, and information provided during session upgrade.

Scripted decision nodes can also use callbacks to provide or request additional information during the authentication process.

Accessing Request Header Data

Scripted Decision Node scripts can access the headers provided by the login request by using the methods of the requestHeaders object.

Note that the script has access to a copy of the headers. Changing their values does not affect the request itself.

The following table lists the methods of the requestHeaders object:

Request Headers Methods
MethodParametersReturn TypeDescription

requestHeaders.get

Header Name (type: String)

String[]

Return the array of string values of the named request header, or null if the property is not set. Note that header names are case-sensitive.

For example:

var headerName = "user-agent";

if (requestHeaders.get(headerName).get(0).indexOf("Chrome") !== -1) {
    outcome = "true";
} else {
    outcome = "false";
}

Accessing Shared State Data

Scripted Decision Node scripts can get access to the shared state within the tree by using the sharedState and transientState objects.

The following table lists the available methods:

Shared State Methods
MethodParametersReturn TypeDescription

sharedState.get

Property Name (type: String)

String

Return the string value of the named shared state property, or null if the property is not set. Note that property names are case-sensitive.

For example, use the following code to get the current authentication level:

var currentAuthLevel = sharedState.get("authLevel");

transientState.get

Property Name (type: String)

String

Return the string value of the named transient state property, or null if the property is not set. Note that property names are case-sensitive.

For example, use the following code to get the value of a previously supplied password:

var givenPassword = transientState.get("password");

Accessing Profile Data

Scripted decision nodes can access profile data through the methods of the idRepository object.

Profile Data Methods
MethodParametersReturn TypeDescription

idRepository.getAttribute

User Name (type: String)

Attribute Name (type: String)

Set

Return the values of the named attribute for the named user.

idRepository.setAttribute

User Name (type: String)

Attribute Name (type: String)

Attribute Values (type: Array)

Void

Set the named attribute as specified by the attribute value for the named user, and persist the result in the user's profile.

idRepository.addAttribute

User Name (type: String)

Attribute Name (type: String)

Attribute Value (type: String)

Void

Add an attribute value to the list of attribute values associated with the attribute name for a particular user.


Setting Session Properties

Scripted Decision Node scripts can create session properties by using the Action API, as follows:

var fr = JavaImporter(
  org.forgerock.openam.auth.node.api.Action
)

with (fr) {
  action = Action.goTo("true").putSessionProperty("mySessionProperty","myPropertyValue").build()
}
import org.forgerock.openam.auth.node.api.Action

action =
  new Action.ActionBuilder("true").putSessionProperty("mySessionProperty","myPropertyValue").build();

Note

Add the property name to the Whitelisted Session Property Names list in the Session Property Whitelist Service; otherwise, it will not be added to sessions. For more information on this service, see "Session Property Whitelist Service".

Add the script to a scripted decision node in your authentication tree. Users that authenticate successfully using that tree will have the property added to their session, as shown in the following output when introspecting a session:

{
    "username": "15249a65-8f9a-4063-9586-a2465963cee4",
    "universalId": "id=15249a65-8f9a-4063-9586-a2465963cee4,ou=user,o=alpha,ou=services,ou=am-config",
    "realm": "/alpha",
    "latestAccessTime": "2020-10-22T15:01:14Z",
    "maxIdleExpirationTime": "2020-10-22T15:31:14Z",
    "maxSessionExpirationTime": "2020-10-22T17:01:13Z",
    "properties": {
        "AMCtxId": "dffed74d-f203-469c-9ed2-34738915baea-5255",
        "mySessionProperty": "myPropertyValue"
    }
}

Accessing Existing Session Properties

Scripted Decision Node scripts can access any existing session properties during a session upgrade request, by using the existingSession object.

The following table lists the methods of the existingSession object:

Existing Session Methods
MethodParametersReturn TypeDescription

existingSession.get

Property Name (type: String)

String

Return the string value of the named existing session property, or null if the property is not set. Note that property names are case-sensitive.

Warning

If the current request is not a session upgrade and does not provide an existing session, the existingSession variable is not declared. Check for a declaration before attempting to access the variable.

For example, use the following code to get the authentication level of the existing session:

if (typeof existingSession !== 'undefined')
{
  existingAuthLevel = existingSession.get("AuthLevel");
}
else
{
  logger.error("Variable existingSession not declared - not a session upgrade.");
}

Using Callbacks

The scripted decision node can use callbacks to provide or request additional information during the authentication process.

For example, the following scripts use the NameCallBack callback to request a "Nickname" value from the user, and adds the returned value to the sharedState map for use elsewhere in the authentication tree:

import org.forgerock.openam.auth.node.api.*;
import javax.security.auth.callback.NameCallback;

if (callbacks.isEmpty()) {
  action = Action.send(new NameCallback("Enter Your Nickname")).build();
} else {
  sharedState.put("Nickname", callbacks.get(0).getName());
  action = Action.goTo("true").build();
}
var fr = JavaImporter(
  org.forgerock.openam.auth.node.api,
  javax.security.auth.callback.NameCallback
);
with (fr) {
  if (callbacks.isEmpty()) {
    action = Action.send(new NameCallback("Enter Your Nickname")).build();
  } else {
    sharedState.put("Nickname", callbacks.get(0).getName());
    action = Action.goTo("true").build();
  }
}

For a list of supported callbacks, see "Supported Callbacks".

Adding Audit Information

The scripted decision node can add information to audit log entries, by using the auditEntryDetail object.

AM appends the value of the object, which can be either plain text, or a JSON object, to the authentication audit logs.

For example, the following Groovy script adds the user's email address to the authentication.audit.json audit log file:

var currentUser = sharedState.get("username");
var attributeToRead = "mail";

auditEntryDetail="Extra Audit: " + currentUser + " email address: " +
  idRepository.getAttribute(currentUser,attributeToRead).iterator().next().toString();

outcome = "true";

The code above adds the information to the auditInfo element, for example:

{
  "_id":"f036618e-e318-4134-ac2a-13e860396103-545013",
  "timestamp":"2020-08-13T18:20:25.202Z",
  "eventName":"AM-NODE-LOGIN-COMPLETED",
  "transactionId":"f036618e-e318-4134-ac2a-13e860396103-544998",
  "trackingIds":[
    "f036618e-e318-4134-ac2a-13e860396103-544956"
  ],
  "principal":[
    "demo"
  ],
  "entries":[
    {
      "info":{
        "nodeOutcome":"true",
        "treeName":"Example",
        "displayName":"Audit Entry",
        "nodeType":"ScriptedDecisionNode",
        "nodeId":"13d40add-137c-4564-ad3c-7d98f7c180c1",
        "authLevel":"0",
        "nodeExtraLogging":{
          "auditInfo":"Extra Audit: demo email address: demo@example.com"
        }
      }
    }
  ]
}

For more information about auditing, see Setting Up Audit Logging.

Read a different version of :