Scripting OpenAM This chapter explains how to use scripting to exact fine control over various aspects of OpenAM. You can use scripts for client-side and server-side authentication, policy conditions, and handling OpenID Connect claims. This chapter covers the following topics: The Scripting Environment The Scripting API Using the Default Scripts For information on managing scripts, see "Managing Scripts" in the Administration Guide and "RESTful Script Management". The Scripting Environment This section introduces how OpenAM executes scripts, and covers thread pools and security configuration. You can use scripts to modify default OpenAM behavior in the following situations, also known as contexts: Client-side Authentication Scripts that are executed on the client during authentication. Client-side scripts must be in JavaScript. Server-side Authentication Scripts are included in an authentication module and are executed on the server during authentication. Scripted authentication modules are an alternative to developing custom authentication modules by using Java as described in "Creating a Custom Authentication Module". A scripted authentication module allows you to customize default authentication behavior by adding Groovy or JavaScript code to the module configuration. To see an example server-side authentication script, see "Default Server-side Authentication Script". Policy Condition Scripts used as conditions within policies. To see an example policy condition script, see "Default Policy Condition Script". OIDC Claims Scripts that gather and populate the claims in a request when issuing an ID token or making a request to the userinfo endpoint. OpenAM implements a configurable scripting engine for each of the context types that are executed on the server. The scripting engines in OpenAM have two main components: security settings, and the thread pool. Security OpenAM scripting engines provide security features for ensuring that malicious Java classes are not directly called. The engines validate scripts by checking all directly-called Java classes against a configurable blacklist and whitelist, and, optionally, against the JVM SecurityManager, if it is configured. Whitelists and blacklists contain class names that are allowed or denied execution respectively. Specify classes in whitelists and blacklists by name or by using regular expressions. Classes called by the script are checked against the whitelist first, and must match at least one pattern in the list. The blacklist is applied after the whitelist, and classes matching any pattern are disallowed. You can also configure the scripting engine to make an additional call to the JVM security manager for each class that is accessed. The security manager throws an exception if a class being called is not allowed to execute. For more information on configuring script engine security, see "Scripting" in the Reference. .Important Points About Script Engine Security The following points should be considered when configuring the security settings within each script engine: The scripting engine only validates directly accessible classes. The security settings only apply to classes that the script directly accesses. If the script calls Foo.a() and then that method calls Bar.b(), the scripting engine will be unable to prevent it. You must consider the whole chain of accessible classes. Access includes actions such as: Importing or loading a class. Accessing any instance of that class. For example, passed as a parameter to the script. Calling a static method on that class. Calling a method on an instance of that class. Accessing a method or field that returns an instance of that class. Potentially dangerous Java classes are blacklisted by default. All Java reflection classes (java.lang.Class, java.lang.reflect.*) are blacklisted by default to avoid bypassing the security settings. The java.security.AccessController class is also blacklisted by default to prevent access to the doPrivileged() methods. You should not remove potentially dangerous Java classes from the blacklist. The whitelists and blacklists match class or package names only. The whitelist and blacklist patterns apply only to the exact class or package names involved. The script engine does not know anything about inheritance, so it is best to whitelist known, specific classes. Thread Pools Each script is executed in an individual thread. Each scripting engine starts with an initial number of threads available for executing scripts. If no threads are available for execution, OpenAM creates a new thread to execute the script, until the configured maximum number of threads is reached. If the maximum number of threads is reached, pending script executions are queued in a number of buffer threads, until a thread becomes available for execution. If a created thread has completed script execution and has remained idle for a configured amount of time, OpenAM terminates the thread, shrinking the pool. For more information on configuring script engine thread pools, see "Scripting" in the Reference. The Scripting API Client-side scripts have access only to the user agent API. The functionality provided by each user agent is different, refer to the API provided by your user agent for more information. Global API Functionality This section covers functionality available to each of the server-side script types. Global API functionality includes: Accessing HTTP Services Debug Logging Accessing HTTP Services OpenAM passes an HTTP client object, httpClient, to server-side scripts. Server-side scripts can call HTTP services with the httpClient.get and httpClient.post methods. The methods return an HttpClientResponse object. HTTP Client Methods Method Parameters Return Type Description httpClient.get URI (type: String) `Request Data` (type: `Map`) HttpClientResponse Perform an HTTP GET on the specified URI with the specified request data and return the response retrieved. httpClient.post URI (type: String) `Body` (type: `String`) `Request Data` (type: `Map`) HttpClientResponse Perform an HTTP POST to the specified URI with the specified body and request data and return the response retrieved. The requestData object is a map in which the keys are cookies and headers. OpenAM ignores other keys. The cookies value, specifying the cookie headers in the request, is a list of maps where the keys are domain, field, and value. The headers value, specifying the headers in the request, is a list of maps where the keys are field, and value. An example requestData JavaScript object using GET would be as follows: var response = httpClient.get("http://example.com:8080/openam/json/users/" + username, { cookies:[ { "domain": ".example.com", "field": "iPlanetDirectoryPro", "value": "E8cDkvlad83kd....KDodkIEIx*DLEDLK...JKD09d" } ], headers:[ { "field": "Content-type", "value": "application/json" } ] }); An example requestData JavaScript object using POST follows: var response = httpClient.post("http://example.com:8080/openam/json/authenticate","{ "authId": "eyAiYWxnIjogIkhTMjU2IiwgInR5cCI6ICJqd3QiIH0.eyAib3RrIjogIm03ODVzN2x sbnR1bjZvbGZ1MHZhOGVtYTQxIiwgInNlc3Npb25JZCI6ICJBUUlDNXdNMkxZNFNmY3lEeDY3QnB PdzJtRU9rUzNpLWhfNDdRWlMwNHBEN1ppdy4qQUFKVFNRQUNNREVBQWxOTEFCUXROak15TURjNU1 UZzROVFUwTXpnNE5qRTNNQS4uKiIsICJyZWFsbSI6ICJkYz1vcGVuYW0sZGM9Zm9yZ2Vyb2NrLGR jPW9yZyIgfQ.VDRqaekQuXBm2lNI29hfwVADLxjepezuO0241VNDsIM", "template": "", "stage": "DataStore1", "callbacks": [ { "type": "NameCallback", "output": [ { "name": "prompt", "value": "User Name:" } ], "input": [ { "name": "IDToken1", "value": "demo" } ] }, { "type": "PasswordCallback", "output": [ { "name": "prompt", "value": "Password:" } ], "input": [ { "name": "IDToken2", "value": "changeit" } ] } ] }", { cookies:[ ], headers:[ { "field": "Content-Type", "value": "application/json" } ] }); To get the form data, you can access the sharedState object to get the data that previous modules in the chain have obtained. For example, if you have a Data Store module in your chain, you can get the username and password from the sharedState object in the script. HTTP client requests are synchronous, blocking until they return. You can, however, set a global timeout for server-side scripts. For details, see "Hints for the Scripted Authentication Module" in the Administration Guide. Server-side scripts can access response data by using the methods listed in the table below. HTTP Client Response Methods Method Parameters Return Type Description HttpClientResponse.getCookies Void Map<String, String> Get the cookies for the returned response, if any exist. HttpClientResponse.getEntity Void String Get the entity of the returned response. HttpClientResponse.getHeaders Void Map<String, String> Get the headers for the returned response, if any exist. HttpClientResponse.getReasonPhrase Void String Get the reason phrase of the returned response. HttpClientResponse.getStatusCode Void Integer Get the status code of the returned response. HttpClientResponse.hasCookies Void Boolean Indicate whether the returned response had any cookies. HttpClientResponse.hasHeaders Void Boolean Indicate whether the returned response had any headers. Debug Logging Server-side scripts can write messages to OpenAM debug logs by using the logger object. OpenAM does not log debug messages from scripts by default. You can configure OpenAM to log such messages by setting the debug log level for the amScript service. For details, see "Debug Logging By Service" in the Administration Guide. The following table lists the logger methods. Logger Methods Method Parameters Return Type Description logger.error Error Message (type: String) Void Write Error Message to OpenAM debug logs if ERROR level logging is enabled. logger.errorEnabled Void Boolean Return true when ERROR level debug messages are enabled. logger.message Message (type: String) Void Write Message to OpenAM debug logs if MESSAGE level logging is enabled. logger.messageEnabled Void Boolean Return true when MESSAGE level debug messages are enabled. logger.warning Warning Message (type: String) Void Write Warning Message to OpenAM debug logs if WARNING level logging is enabled. logger.warningEnabled Void Boolean Return true when WARNING level debug messages are enabled. Authentication API Functionality This section covers the available functionality when Scripting authentication modules use client-side and server-side authentication script types. Authentication API functionality includes: Accessing Authentication State Accessing Profile Data Accessing Client-Side Script Output Data Accessing Request Data Accessing Authentication State OpenAM passes authState and sharedState objects to server-side scripts in order for the scripts to access authentication state. Server-side scripts can access the current authentication state through the authState object. The authState value is SUCCESS if the authentication is currently successful, or FAILED if authentication has failed. Server-side scripts must set a value for authState before completing. If an earlier authentication module in the authentication chain has set the login name of the user, server-side scripts can access the login name through username. The following authentication modules set the login name of the user: Anonymous Certificate Data Store Federation HTTP Basic JDBC LDAP Membership RADIUS SecurID, Windows Desktop SSO Windows NT Accessing Profile Data Server-side authentication scripts can access profile data through the methods of the idRepository object. Profile Data Methods Method Parameters Return Type Description 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. Accessing Client-Side Script Output Data Client-side scripts add data they gather into a String object named clientScriptOutputData. Client-side scripts then cause the user-agent automatically to return the data to OpenAM by HTTP POST of a self-submitting form. Accessing Request Data Server-side scripts can get access to the login request by using the methods of the requestData object. The following table lists the methods of the requestData object. Note that this object differs from the client-side requestData object (see "HTTP Client Methods") and contains information about the original authentication request made by the user. Request Data Methods Method Parameters Return Type Description requestData.getHeader Header Name (type: String) String Return the String value of the named request header, or null if parameter is not set. requestData.getHeaders Header Name (type: String) String[] Return the array of String values of the named request header, or null if parameter is not set. requestData.getParameter Parameter Name (type: String) String Return the String value of the named request parameter, or null if parameter is not set. requestData.getParameters Parameter Name (type: String) String[] Return the array of String values of the named request parameter, or null if parameter is not set. Authorization API Functionality This section covers functionality available when scripting authorization using the policy condition script context type. Accessing Authorization State Server-side scripts can access the current authorization state through the following objects: Authorization State Objects Object Type Description authorized Boolean Return true if the authorization is currently successful, or false if authorization has failed. Server-side scripts must set a value for authorized before completing. environment Map<String, Set<String>> Describe the environment passed from the client making the authorization request. For example, the following shows a simple `environment` map with a single entry: "environment": { "IP": [ "127.0.0.1" ] } resourceURI String Specify the URI of the resource to which authorization is being requested. username String Specify the user ID of the subject that is requesting authorization. Accessing Profile Data Server-side authorization scripts can access profile data of the subject of the authorization request through the methods of the identity object. To access the profile data of the subject, they must be logged in and their SSO token must be available. Authorization Script Profile Data Methods Method Parameters Return Type Description identity.getAttribute Attribute Name (type: String) Set Return the values of the named attribute for the subject of the authorization request. identity.setAttribute Attribute Name (type: String) `Attribute Values` (type: `Array`) Void Set the named attribute to the values specified by the attribute value for the subject of the authorization request. identity.addAttribute 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 the subject of the authorization request. identity.store None Void Commit any changes to the identity repository. You must call store() otherwise changes will be lost when the script completes. Accessing Session Data Server-side authorization scripts can access session data of the subject of the authorization request through the methods of the session object. To access the session data of the subject, they must be logged in and their SSO token must be available. Authorization Script Session Methods Method Parameters Return Type Description session.getProperty Property Name (type: String) String Retrieve properties from the session associated with the subject of the authorization request. For example, AuthLevel. Setting Authorization Responses Server-side authorization scripts can return information in the response to an authorization request. Authorization Script Response Methods Method Parameters Return Type Description responseAttributes.put Attribute Name (type: String) `Attribute Values` (type: `Array`) Void Add an attribute to the response to the authorization request. advice.put Advice Key (type: String) `Advice Values` (type: `Array`) Void Add advice key-value pairs to the response to a failing authorization request. ttl TTL Value (type: Integer) Void Add a time-to-live value to the response to a successful authorization, after which the decision is no longer valid. OIDC Claims API Functionality This section covers functionality available when scripting OIDC claim handling using the OIDC claims script context type. Accessing OpenID Connect Requests Server-side scripts can access the OpenID Connect request through the following objects: OIDC Request Objects Object Type Description scopes Set<String> Contains a set of the requested scopes. For example: [ "profile", "openid" ] identity Class Contains a representation of the identity of the resource owner. For more details, see the `com.sun.identity.idm.AMIdentity` class in the link:../apidocs/index.html?com/sun/identity/idm/AMIdentity.html[OpenAM Javadoc, window=\_top]. session Class Contains a representation of the user’s session object if the request contained a session cookie. For more details, see the `com.iplanet.sso.SSOToken` class in the link:../apidocs/index.html?com/iplanet/sso/SSOToken.html[OpenAM Javadoc, window=\_top]. claims Map<String, Object> Contains a map of the claims the server provides by default. For example: { "sub": "248289761001", "updated_at": "1450368765" } requestedClaims Map<String, Set<String>> Contains requested claims if the claims query parameter is used in the request and Enable "claims_parameter_supported" is checked in the OAuth2 provider service configuration, otherwise is empty. For more information see link:http://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter["Requesting Claims using the "claims" Request Parameter", window=\_blank] in the __OpenID Connect Core 1.0__ specification. Example: { "given_name": { "essential": true, "values": [ "Demo User", "D User" ] }, "nickname": null, "email": { "essential": true } } Using the Default Scripts This section covers the default scripts provided in OpenAM. These scripts act as templates for creating your own scripts. They are global and can be used in any realm, and cannot be deleted. Editing a default script will affect every authentication module, policy condition, or OIDC claim configuration that uses the script. Default Server-side Authentication Script This section demonstrates how to use the default server-side authentication script in a Scripted Authentication module. The default server-side authentication script only authenticates a subject when the current time on the OpenAM server is between 09:00 and 17:00. The script also uses the logger and httpClient functionality provided in the scripting API. To examine the contents of the default server-side authentication script in the OpenAM console browse to Realms > Top Level Realm > Scripts, and then click Scripted Module - Server Side. For more information on the functions available for use in server-side authentication scripts, see "The Scripting API". Preparing OpenAM OpenAM requires a small amount of configuration before trying the example server-side authentication script. You must first create a Scripted authentication module, and then include it in an authentication chain, which can then be used when logging in to OpenAM. The procedures in this section are: "To Create a Scripted Authentication Module that Uses the Default Server-side Authentication Script" "To Create an Authentication Chain that Uses a Scripted Authentication Module" To Create a Scripted Authentication Module that Uses the Default Server-side Authentication Script In this procedure create a Scripted Authentication module, and link it to the default server-side authentication script. Log in as an OpenAM administrator, for example amadmin. Click Realms > Top Level Realm > Authentication > Modules. On the Authentication Modules page, click Add Module. On the New Module page, enter a module name, such as myScriptedAuthModule, in the Type drop-down menu, select Scripted Module, and then click Create. On the module configuration page: Uncheck the Client-side Script Enabled checkbox. In the Server-side Script drop-down menu, select Scripted Module - Server Side. Click Save Changes. To Create an Authentication Chain that Uses a Scripted Authentication Module In this procedure create an authentication chain that uses a Data Store authentication module and the Scripted authentication module created in the previous procedure. Log in as an OpenAM administrator, for example amadmin. Click Realms > Top Level Realm > Authentication > Chains. On the Authentication Chains page, click Add Chain. On the Add Chain page, enter a name, such as myScriptedChain, and then click Create. On the Edit Chain tab, click Add a Module. In the New Module dialog box: In the Select Module drop-down menu, select DataStore. In the Select Criteria drop-down menu, select Required. Click OK. The Data Store authentication module checks the user credentials, whereas the Scripted authentication module does not check credentials, but instead only checks that the authentication request is processed during working hours. Without the Data Store module, the username in the Scripted authentication module cannot be determined. Therefore, do not configure the Scripted authentication module (server-side script) as the first module in an authentication chain, because it needs a username. On the Edit Chain tab, click Add Module. In the New Module dialog box: In the Select Module drop-down menu, select the Scripted Module from the previous procedure, for example myScriptedAuthModule. In the Select Criteria drop-down menu, select Required. Click OK. The resulting chain resembles the following: + On the Edit Chain tab, click Save Changes. Trying the Default Server-side Authentication Script This section shows how to log in using an authentication chain that contains a Scripted authentication module, which in turn uses the default server-side authentication script. To Login to OpenAM Using a Chain Containing a Scripted Authentication Module Log out of OpenAM. In a browser, navigate to the OpenAM login URL, and specify the authentication chain created in the previous procedure as the value of the service query parameter. For example: https://openam.example.com:8443/openam/XUI/#login/&service=myScriptedChain Log in as user demo with password changeit. If login is successful, the user profile page appears. The script will also output messages, such as the following in the debug/Authentication log file: amScript:05/08/2015 11:31:21:835 AM CEST: Thread[pool-19-thread-5,5,main] Starting server-side JavaScript amScript:05/08/2015 11:31:21:837 AM CEST: Thread[pool-19-thread-5,5,main] User: demo amScript:05/08/2015 11:31:21:837 AM CEST: Thread[pool-19-thread-5,5,main] Current time: 11 amScript:05/08/2015 11:31:21:837 AM CEST: Thread[pool-19-thread-5,5,main] Authentication allowed! The default server-side authentication script outputs log messages at the message and error level. OpenAM does not log debug messages from scripts by default. You can configure OpenAM to log such messages by setting the debug log level for the amScript service. For details, see "Debug Logging By Service" in the Administration Guide. (Optional) To test that the script is being used as part of the login process, edit the script to alter the times when authentication is allowed: Log out the demo user. Log in as an OpenAM administrator, for example amadmin. Click Realms > Top Level Realm > Scripts > Scripted Module - Server Side. In the script, swap the values for START_TIME and END_TIME, for example: var START_TIME = 17; var END_TIME = 9; // Click Save. Repeat steps 1, 2, and 3 above, logging into the module as the demo user as before. The authentication result will be the opposite of the previous result, as the allowed times have inverted. Default Policy Condition Script This section demonstrates how to use the sample policy condition script as part of an authorization policy. To examine the contents of the sample policy condition script in the OpenAM console browse to Realms > Top Level Realm > Scripts, and then click Scripted Policy Condition. The default policy condition script demonstrates how to access a user’s profile information, use that information in HTTP calls, and make a policy decision based on the outcome. For more information on the functions available for use in policy condition scripts, see "The Scripting API". Preparing OpenAM OpenAM requires a small amount of configuration before trying the default policy condition script. The default policy condition script requires that the subject of the policy has an address in their profile. The script compares the address to the country in the resource URL and to the country from which the request originated, as determined by an external GeoIP web service. The demo user also requires access to evaluate policies. The procedures in this section are: "To Add an Address to the Demo User" "To Allow the Demo User to Evaluate a Policy" "To Create a Policy that Uses the Default Policy Condition Script" "To Enable Message-level Logging for Policy Evaluation" To Add an Address to the Demo User In this procedure, add an address value to the demo user’s profile. The default policy condition script uses the address when performing policy evaluation. Log in as an OpenAM administrator, for example amadmin. Click Realms > Top Level Realm > Subjects. On the User tab, click the demo user. In Home Address, enter a valid address. For example: 201 Mission St, Suite 2900, San Francisco, CA 94105 Click Save. To Allow the Demo User to Evaluate a Policy In this procedure, add the demo user to a group and assign the privilege required to perform policy evaluations. Log in as an OpenAM administrator, for example amadmin. Click Realms > Top Level Realm > Subjects. On the Group tab, click New, enter an ID for the group, such as policyEval, and then click OK. On the User tab: Click the demo user. Click the Group tab. In the Available box, select the group created in step 3, and then click Add. Click Save. Click Realms > Top Level Realm > Privileges. Click the group created in step 3, for example policyEval. On the Privileges page, select Read and write access to all realm and policy properties. Click Save. To Create a Policy that Uses the Default Policy Condition Script In this procedure, create a policy that uses the default policy condition script. Policy evaluations can then be performed to test the script functionality. Log in as an OpenAM administrator, for example amadmin. Click Realms > Top Level Realm > Authorization > Policy Sets. On the Policy Sets page, select Default Policy Set. On the Default Policy Set page, click Add a Policy. Define the policy as follows: Enter a name for the policy. Define resources to which the policy applies: Select URL from the Resource Type drop down list. Select the resource pattern ://:*/* from the Resources drop down list. Click Add. The ://:*/* resource appears in the Resources field. Click Add Resource to add a second resource to the policy. Select the resource pattern ://:*/? from the Resources drop down list. Click Add. The ://:*/? resource appears along with the ://:*/* resource in the Resources field. Click Create to create the policy. The Resources tab appears as follows: Specify actions to which the policy applies: Select the Actions tab. Select GET from the Add an Action drop down list. The GET action appears in the list of actions. The default state for the GET action is Allow. The Actions tab appears as follows: Click Save Changes. Configure subjects to which the policy applies: Select the Subjects tab. Click the edit icon—the pencil. Select Authenticated Users from the Type drop down list. Click the OK icon—the check mark. The Subjects tab appears as follows: Click Save Changes. Configure environments in which the policy applies: Select the Environments tab. Click Add an Environment Condition. Select Script from the Type drop down list. Select Scripted Policy Condition from the Script Name drop down list. Click the OK icon—the check mark. The Environments tab appears as follows: Click Save Changes. No additional configuration is required in the Response Attributes or Details tabs. To Enable Message-level Logging for Policy Evaluation The default policy condition script writes to the debug logs at the message level. Message-level debug logging is not enabled for policy evaluation by default. This section shows how to enable message-level debug logging for policy evaluation, so that logger output from the default policy condition script can be viewed in the Entitlement debug log. Log in as an OpenAM administrator, for example amadmin. Visit the Debug.jsp page, for example: https://openam.example.com:8443/openam/Debug.jsp. In the Debug instances drop-down, select Entitlement. In the Level drop-down, choose the debug level required. In this example, select Message. Click Submit, and on the summary page that appears, click Confirm. Message-level debug logging is now enabled for policy evaluation. Trying the Default Policy Condition Script This section demonstrates using a policy that contains the default policy condition script. To evaluate against a policy, you must first obtain an SSO token for the subject performing the evaluation, in this case the demo user. You can then make a call to the policies?_action=evaluate endpoint, including some environment information, which the policy uses to make an authorization decision. To Evaluate a Policy Obtain an SSO Token for the demo user: curl \ --request POST \ --header "X-OpenAM-Username: demo" \ --header "X-OpenAM-Password: changeit" \ https://openam.example.com:8443/openam/json/authenticate { "tokenId": "AQIC5wM2...", "successUrl": "/openam/console" } Send an evaluation request to the policies endpoint, using the SSO token of the demo user in the iPlanetDirectoryPro header. In the JSON data, set the subject property to also be the SSO token of the demo user. In the resources property, include a URL that resides on a server in the same country as the address set for the demo user. In the environment property, include an IP address that is also based in the same country as the user and the resource. The example below uses the ForgeRock Community web site URL and an IP address from a ForgeRock office, both located in the United States: curl \ --request POST \ --header "Content-Type: application/json" \ --header "iPlanetDirectoryPro: AQIC5wM2..." \ --data '{ "resources": [ "http://www.forgerock.org:80/index.html" ], "application": "iPlanetAMWebAgentService", "subject": { "ssoToken": "AQIC5wM2..."}, "environment": { "IP": [ "38.99.39.210" ] } }' \ https://openam.example.com:8443/openam/json/policies?_action=evaluate [ { "advices": {}, "ttl": 9223372036854775807, "resource": "http://www.forgerock.org:80/index.html", "actions": { "POST": true, "GET": true }, "attributes": { "countryOfOrigin": [ "United States" ] } } ] If the country in the subject’s profile matches the country determined from the source IP in the environment and the country determined from the resource URL, then OpenAM returns a list of actions available. The script will also add an attribute to the response called countryOfOrigin with the country as the value. If the countries do not match, no actions are returned. In the following example, the resource URL is based in France, while the IP and user’s address in the profile are based in the United States: curl -X POST \ -H "Content-Type: application/json" \ -H "iPlanetDirectoryPro: AQIC5wM2..." \ -d '{ "resources": [ "http://www.forgerock.fr:80/index.html" ], "application": "iPlanetAMWebAgentService", "subject": { "ssoToken": "AQIC5wM2..."}, "environment": { "IP": [ "38.99.39.210" ] } }' \ 'https://openam.example.com:8443/openam/json/policies?_action=evaluate' [ { "advices": {}, "ttl": 9223372036854775807, "resource": "http://www.forgerock.fr:80/index.html", "actions": {}, "attributes": {} } ] Default OIDC Claims Script This section demonstrates how to use the default OIDC claims script to return the profile attributes of a user in response to an OpenID Connect request for the profile scope. The default OIDC claims script maps the following claims to the profile scope: zoneinfo family_name locale name To examine the contents of the default OIDC claims script in the OpenAM console browse to Realms > Top Level Realm > Scripts, and then click OIDC Claims Script. For more information on the functions available for use in OIDC claim scripts, see "The Scripting API". Preparing OpenAM OpenAM requires a small amount of configuration before trying the example OIDC claims script. You must first create an OAuth2 provider with OpenID Connect settings, and register an OpenID Connect client, before you can authenticate to the client using a web browser. The procedures in this section are: "To Create an OpenID Connect Provider Service" "To Register an OpenID Connect Client" To Create an OpenID Connect Provider Service Follow the steps in this procedure to create an OpenID Connect provider service by using the wizard. Log in to OpenAM as an administrator, for example amadmin. Click Realms > Top Level Realm > Configure OAuth Provider > Configure OpenID Connect. On the Configure OpenID Connect page, accept the default values and then click Create. Navigate to Realms > Top Level Realm > Services, click OAuth2 Provider, and verify that the value for OIDC Claims Script is the default script, OIDC Claims Script. For a more detailed explanation and example of creating an OpenID Connect provider service, see "Configuring OpenAM As OpenID Connect Provider" in the Administration Guide. To Register an OpenID Connect Client Follow the steps in this procedure to create an OpenID Connect client agent profile. Log in to OpenAM as an administrator, for example amadmin. Click Realms > Top Level Realm > Agents > OAuth 2.0/OpenID Connect Client. In the Agent table, click New. Enter a name for the client, such as oidcTest, provide a password, and then click Create. On the OAuth 2.0/OpenID Connect Client page, click the agent name to configure the agent. On the edit client page: In Redirection URIs, enter an example URI such as http://www.example.com. In Scope(s), enter both profile and openid. The profile scope will return details about the subject such as given name and timezone. The openid scope indicates this is an OpenID Connect client. In Display name, enter the name of the client as it will be displayed on the consent page, for example OIDC Claims Script Client. Save your work. For a more detailed explanation and examples of registering an OpenID Connect client, see "Registering OpenID Connect Relying Parties" and "Configuring OAuth 2.0 and OpenID Connect 1.0 Clients" in the Administration Guide. Trying the Default OIDC Claims Script This section shows how to authenticate to a registered OpenID Connect client and request scopes from OpenAM, which in turn uses the default OIDC Claims script to populate the scope with claims and profile values. To Authenticate to an OIDC Client and use the Default OIDC Claims Script Log out of OpenAM. In an Internet browser, navigate to the OpenAM OAuth 2.0 authorization endpoint, /oauth2/authorize, and specify the following query parameters, with the values you configured in the agent profile: Query parameters for OpenID Connect Authorization to an Agent Profile Query Parameter Agent Profile Property Value client_id Name of the agent, for example oidcTest. redirect_uri Redirection URIs, for example http://www.example.com. response_type Response Types, for example code. scope Scope(s), for example openid profile. For example: http://openam.example.com:8080/openam/oauth2/authorize?client_id=oidcTest&redirect_uri=http://www.example.com&response_type=code&scope=openid profile Log in to OpenAM as demo, with password changeit. On the consent page, expand the panel labelled Your personal information to see the claim values the default OIDC script has populated into the requested profile scope. Click Allow to be redirected to the Redirection URI specified in the agent profile. The authorization code is appended to the redirection URI as the value of the code query parameter. Extending OpenAM Building SAML v2.0 Service Providers With Fedlets