Script bindings
Each script type exposes a number of bindings, objects that Identity Cloud injects into the script execution context. The bindings provide a stable way of accessing Identity Cloud functionality, without the need to allowlist Java classes. Scripts are provided with all the bindings for their context at the point of execution.
Find information about context-specific bindings in the documentation for each script type.
Identity Cloud has introduced a next-generation scripting engine that offers several benefits, including enhanced script bindings. For decision node scripts, the availability and usage of bindings depend on the script engine version of the script: legacy or next-generation. Both versions are described in this section. The next-generation script engine is only available to the Scripted decision node API. For information about migrating to the enhanced scripting engine, refer to Migrating to next-generation scripts. |
Common bindings
The following bindings are common to many authentication and authorization scripts. Use these bindings to access data and perform script operations such as logging.
Binding | Description | Further information |
---|---|---|
|
Make outbound HTTP calls. |
|
|
Write a message to the Identity Cloud debug log. |
|
|
Access the name of the running script. |
|
|
Reference environment secrets and variables (ESVs) in scripts. |
Access HTTP services
Call HTTP services with the httpClient.send
method. HTTP client requests are asynchronous,
unless you invoke the get()
method on the returned object.
The httpClient
binding uses native JavaScript objects, and behaves like the
Fetch API.
To invoke an HTTP request:
-
ResponseScriptWrapper httpClient.send(String uri, Map requestOptions).get()
Sends a synchronous request to the specified URI with request options. The Map parameter is a native JavaScript object that supports
method
,headers
,token
, andbody
as request options. -
ResponseScriptWrapper httpClient.send(String uri).get()
Sends a synchronous GET request with no additional request options.
To access response data:
-
Map response.formData()
-
Map response.json()
-
String response.text()
The following fields provide response status information:
Field Type headers
Map
ok
boolean
status
integer
statusText
String
The response is similar to Response object behavior.
To invoke a synchronous HTTP request:
-
HTTPClientResponse httpClient.send(Request request).get()
To access response data:
-
JSON.parse(response.getEntity().getString())
HttpClientResponse
methods:
-
Map<String, String> getCookies()
-
String getEntity
-
Map<String, String> getHeaders()
-
String getReasonPhrase()
-
Integer getStatusCode()
-
Boolean hasCookies
-
Boolean hasHeaders
The following example uses the httpClient
binding to send a synchronous authentication request and check for success.
// import a library script that handles authentication
var authLib = require("authLib");
// use the library function to get authentication token
var bearerToken = authLib.generateBearer(nodeState);
var requestOptions = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
token: bearerToken, // Equivalent to Authorization header
body: {
username: "demo"
}
}
var requestURL = "https://my.auth.server/authenticate";
var response = httpClient.send(requestURL, requestOptions).get();
if (response.status === 200) {
action.goTo("true");
} else {
action.goTo("false");
}
var fr = JavaImporter(org.forgerock.openam.auth.node.api.Action);
var requestURL = "https://my.auth.server/authenticate";
var request = new org.forgerock.http.protocol.Request();
request.setUri(requestURL);
request.setMethod("POST");
request.getHeaders().add("Content-Type", "application/json;");
request.getHeaders().add("Authorization", "Bearer abcd-1234");
request.setEntity(JSON.stringify({"username": "demo"}));
var response = httpClient.send(request).get();
var responseCode = response.getStatus().getCode();
if (responseCode === 200) {
action = fr.Action.goTo("true").build();
} else {
action = fr.Action.goTo("false").build();
}
The httpclient
binding also supports asynchronous requests so that you can
perform non-blocking operations, such as recording logging output after the script has completed.
To make an asynchronous request, use the same method signatures to send the request but without calling get()
on the returned object:
public Promise<ResponseScriptWrapper, HttpClientScriptException> send(String uri)
public Promise<ResponseScriptWrapper, HttpClientScriptException> send(String uri, Map<String, Object> requestOptions)
public Promise<Response, NeverThrowsException> send(Request request)
For example:
var requestURL = "https://my.auth.server/audit";
var response = httpClient.send(requestURL).then((response) => {
if (!response) {
logger.error("Bad response from " + requestURL);
return;
}
if (response.status != 200) {
logger.error("Unexpected response: " + response.statusText);
return;
}
logger.debug("Returned from async request");
});
action.goTo("true");
var fr = JavaImporter(
org.forgerock.http.protocol.Request,
org.forgerock.http.protocol.Response,
org.forgerock.openam.auth.node.api.Action);
var request = new fr.Request();
request.setUri("https://my.auth.server/audit");
request.setMethod("GET");
var response = httpClient.send(request).then((response) => {
if (!response) {
logger.error("Bad response from " + requestURL);
return;
}
var status = response.getStatus().getCode();
if (status != 200) {
logger.error("Unexpected response: " + response.getEntity().getString());
return;
}
logger.message("Returned from async request");
});
action = fr.Action.goTo("true").build();
The |
Log script messages
Write messages to Identity Cloud debug logs by using the logger
object.
Scripts that create debug messages have their own logger which is created after the script has executed at least once.
Logger names use the format: scripts.<context>.<script UUID>.(<script name>); for example,
`scripts.OIDC_CLAIMS.36863ffb-40ec-48b9-94b1-9a99f71cc3b5.(OIDC Claims Script)
.
For information about debug logs, refer to Get audit and debug logs.
The ScriptedLoggerWrapper
is based on the SLF4J logging framework. You can log messages at the following levels:
-
Trace
-
Debug (default level for development tenant environments)
-
Info
-
Warn (default level for staging and production environments)
-
Error
var traceEnabled = logger.isTraceEnabled();
logger.trace("Trace with arg {}", arg);
var debugEnabled = logger.isDebugEnabled();
logger.debug("Debug with arg {}", arg);
var infoEnabled = logger.isInfoEnabled();
logger.info("Info with arg {}", arg);
var warnEnabled = logger.isWarnEnabled();
logger.warn("Warn with arg {}", arg);
var errorEnabled = logger.isErrorEnabled();
logger.error("Error with arg {}", arg);
The Debug
logger lets you log messages at the following levels:
-
Message
-
Warning
-
Error
var messageEnabled = logger.messageEnabled();
logger.message("Message with arg {}", arg);
var warnEnabled = logger.warningEnabled();
logger.warning("Warn with arg {}", arg);
var errorEnabled = logger.errorEnabled();
logger.error("Error with arg {}", arg);
Reference ESVs in scripts
The systemEnv
binding, available to all script types,
provides the following methods shown with their Java signatures:
String getProperty(String propertyName);
String getProperty(String propertyName, String defaultValue);
<T> T getProperty(String propertyName, String defaultValue, Class<T> returnType);
where:
-
propertyName
refers to an ESV. For details, refer to Introduction to ESVs.The
propertyName
always starts withesv.
; for example,esv-my-variable
.Make sure the
propertyName
is specific enough to distinguish it from all other ESVs defined. -
defaultValue
is a default value to use when no ESV matchespropertyName
.The
defaultValue
must not benull
. -
returnType
is one of the following fully-qualified Java class names:-
java.lang.Boolean
-
java.lang.Double
-
java.lang.Integer
-
java.lang.String
-
java.util.List
-
java.util.Map
-
The getProperty(String propertyName)
method returns null
when the propertyName
is not valid.
For example:
var myProperty = systemEnv.getProperty('esv.my.variable');
var myDefault = systemEnv.getProperty('esv.nonexisting.variable', 'defaultValue');
var myDouble = systemEnv.getProperty('esv.double.variable', '0.5', java.lang.Double);
var map = systemEnv.getProperty('esv.map.variable', '{"defaultKey":"defaultValue"}', java.util.Map);