How To
ForgeRock Identity Platform
Does not apply to Identity Cloud

How do I create an authentication tree in AM 5.5.x, 6.x and 7.x using REST or Amster?

Last updated Feb 24, 2021

The purpose of this article is to provide information on creating an authentication tree using either the REST API or Amster in AM.


5 readers recommend this article

Overview

When creating authentication trees using either the REST API or Amster, you should be aware of the following key points:

  • You must re-create each node in order to create a new authentication tree.
  • Each node must have a valid UUID as its identifier; you can generate UUIDs online, for example: Online UUID Generator. If you don't use a valid UUID, authentication will fail and you will see an error similar to the following in the Authentication debug log: ERROR: Could not get SMS service: authenticationTreesService java.lang.IllegalArgumentException: Invalid UUID string: 12345
  • The entryNodeId field specified when creating the authentication tree is the UUID of the first node in the tree.
  • The outcome field specified when creating the authentication tree is the UUID of the next node; in this way you can move between the nodes.
  • The Success/Failure nodes have static UUIDs that remain constant across all authentication trees and AM versions. These UUIDs are as follows:
    • Success node: 70e691a5-1e33-4ac3-a356-e7b6d60d92e0
    • Failure node: e301438c-0bd0-429c-ab0c-66126501069a
Note

There are known issues that prevent custom nodes being created via Amster: OPENAM-13157 (Custom Authentication Nodes not being exported correctly) and OPENAM-14008 (creating custom auth node fails with amster). As a result, you should create custom nodes via REST instead.

The following sections provide examples for creating a simple tree that consists of three nodes (UsernameCollectorNode, PasswordCollectorNode and DataStoreDecisionNode):

The resulting tree created from these examples looks like this:

Creating a tree using the REST API

Note

Please observe the following when constructing REST calls:

  • Make the REST call to the actual AM/OpenAM server URL (not lb).
  • Change the name of the iPlanetDirectoryPro header to the name of your actual session cookie.
  • Set this session cookie header to the token returned when you authenticated.
  • Ensure the Accept-API-Version header contains valid resource versions (AM 5 and later).

See How do I avoid common issues with REST calls in AM (All versions)? for further information.

The following example demonstrates creating the authentication tree using the REST API:

  1. Generate UUIDs for each of the nodes you want to create. For example:
    • UsernameCollectorNode: 8f9d2280-caa7-433f-93a9-1f64f4cae60a
    • PasswordCollectorNode: 54f14341-d1b7-436f-b159-d1f9b6c626eb
    • DataStoreDecisionNode: 3fc7ce22-fc79-4131-85f2-f1844709d042
  2. Authenticate as an admin user. For example: $ curl -X POST -H "X-OpenAM-Username: amadmin" -H "X-OpenAM-Password: cangetinam" -H "Content-Type: application/json" -H "Accept-API-Version: resource=2.1" http://host1.example.com:8080/openam/json/realms/root/authenticate?authIndexType=service&authIndexValue=adminconsoleservice Example response: { "tokenId": "AQIC5wM2LY4SfcxsuvGEjcsppDSFR8H8DYBSouTtz3m64PI.*AAJTSQACMDIAAlNLABQtNTQwMTU3NzgxODI0NzE3OTIwNAEwNDU2NjE0*", "successUrl": "/openam/console", "realm": "/" }
  3. Create the UsernameCollector node using the following curl command, where the UUID is the one you generated: $ curl -X PUT -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" -H "Content-Type: application/json" -H "Accept-API-Version: resource=1.0" -H "If-None-Match: *" -d '{"_id":"8f9d2280-caa7-433f-93a9-1f64f4cae60a","_type":{"_id":"UsernameCollectorNode","name":"Username Collector"}}' 'http://host1.example.com:8080/openam/json/realms/root/realms/employees/realm-config/authentication/authenticationtrees/nodes/UsernameCollectorNode/8f9d2280-caa7-433f-93a9-1f64f4cae60a' Example response: {"_id":"8f9d2280-caa7-433f-93a9-1f64f4cae60a","_type":{"_id":"UsernameCollectorNode","name":"Username Collector","collection":true}}
  4. Create the PasswordCollector node using the following curl command, where the UUID is the one you generated: $ curl -X PUT -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" -H "Content-Type: application/json" -H "Accept-API-Version: resource=1.0" -H "If-None-Match: *" -d '{"_id":"54f14341-d1b7-436f-b159-d1f9b6c626eb","_type":{"_id":"PasswordCollectorNode","name":"Password Collector"}}' 'http://host1.example.com:8080/openam/json/realms/root/realms/employees/realm-config/authentication/authenticationtrees/nodes/PasswordCollectorNode/54f14341-d1b7-436f-b159-d1f9b6c626eb' Example response: {"_id":"54f14341-d1b7-436f-b159-d1f9b6c626eb","_type":{"_id":"PasswordCollectorNode","name":"Password Collector","collection":true}}
  5. Create the DataStoreDecision node using the following curl command, where the UUID is the one you generated: $ curl -X PUT -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" -H "Content-Type: application/json" -H "Accept-API-Version: resource=1.0" -H "If-None-Match: *" -d '{"_id":"3fc7ce22-fc79-4131-85f2-f1844709d042","_type":{"_id":"DataStoreDecisionNode","name":"Data Store Decision"}}' 'http://host1.example.com:8080/openam/json/realms/root/realms/employees/realm-config/authentication/authenticationtrees/nodes/DataStoreDecisionNode/3fc7ce22-fc79-4131-85f2-f1844709d042' Example response: {"_id":"3fc7ce22-fc79-4131-85f2-f1844709d042","_type":{"_id":"DataStoreDecisionNode","name":"Data Store Decision","collection":true}}
  6. Create the authentication tree with these three nodes, where the UUIDs are the ones you used to create the nodes. Ensure you set entryNodeId to the UUID of the first node and set the outcome of each node to the UUID of the next node. For example: $ curl -X PUT -H "iPlanetDirectoryPro: AQIC5wM2LY4Sfcxs...EwNDU2NjE0*" -H "Content-Type: application/json" -H "Accept-API-Version: resource=1.0" -H "If-None-Match: *" -d '{"entryNodeId":"8f9d2280-caa7-433f-93a9-1f64f4cae60a","nodes":{"8f9d2280-caa7-433f-93a9-1f64f4cae60a":{"displayName":"Username Collector","nodeType":"UsernameCollectorNode","connections":{"outcome":"54f14341-d1b7-436f-b159-d1f9b6c626eb"}},"54f14341-d1b7-436f-b159-d1f9b6c626eb":{"displayName":"Password Collector","nodeType":"PasswordCollectorNode","connections":{"outcome":"3fc7ce22-fc79-4131-85f2-f1844709d042"}},"3fc7ce22-fc79-4131-85f2-f1844709d042":{"displayName":"Data Store Decision","nodeType":"DataStoreDecisionNode","connections":{"false":"e301438c-0bd0-429c-ab0c-66126501069a","true":"70e691a5-1e33-4ac3-a356-e7b6d60d92e0"}}}}' 'http://host1.example.com:8080/openam/json/realms/root/realms/employees/realm-config/authentication/authenticationtrees/trees/MyNewAuthTree' Example response: {"entryNodeId":"8f9d2280-caa7-433f-93a9-1f64f4cae60a","nodes":{"8f9d2280-caa7-433f-93a9-1f64f4cae60a":{"nodeType":"UsernameCollectorNode","displayName":"Username Collector","connections":{"outcome":"54f14341-d1b7-436f-b159-d1f9b6c626eb"}},"54f14341-d1b7-436f-b159-d1f9b6c626eb":{"nodeType":"PasswordCollectorNode","displayName":"Password Collector","connections":{"outcome":"3fc7ce22-fc79-4131-85f2-f1844709d042"}},"3fc7ce22-fc79-4131-85f2-f1844709d042":{"nodeType":"DataStoreDecisionNode","displayName":"Data Store Decision","connections":{"false":"e301438c-0bd0-429c-ab0c-66126501069a","true":"70e691a5-1e33-4ac3-a356-e7b6d60d92e0"}}},"_id":"MyNewAuthTree"}

Creating a tree using Amster

The following example demonstrates creating the authentication tree using Amster:

  1. Generate UUIDs for each of the nodes you want to create. For example:
    • UsernameCollectorNode: 8f9d2280-caa7-433f-93a9-1f64f4cae60a
    • PasswordCollectorNode: 54f14341-d1b7-436f-b159-d1f9b6c626eb
    • DataStoreDecisionNode: 3fc7ce22-fc79-4131-85f2-f1844709d042
  2. Create the UsernameCollector node: $ create UsernameCollector --realm employees --id 8f9d2280-caa7-433f-93a9-1f64f4cae60a --body '{"_id":"8f9d2280-caa7-433f-93a9-1f64f4cae60a","_type":{"_id":"UsernameCollectorNode","name":"Username Collector"}}' ===> { "_rev": "1086377982", "_type": { "_id": "UsernameCollectorNode", "name": "Username Collector", "collection": true }, "_id": "8f9d2280-caa7-433f-93a9-1f64f4cae60a" }
  3. Create the PasswordCollector node: $ create PasswordCollector --realm employees --id 54f14341-d1b7-436f-b159-d1f9b6c626eb --body '{"_id":"54f14341-d1b7-436f-b159-d1f9b6c626eb","_type":{"_id":"PasswordCollectorNode","name":"Password Collector"}}' ===> { "_rev": "-747204328", "_type": { "_id": "PasswordCollectorNode", "name": "Password Collector", "collection": true }, "_id": "54f14341-d1b7-436f-b159-d1f9b6c626eb" }
  4. Create the DataStoreDecision node: $ create DataStoreDecision --realm employees --id 3fc7ce22-fc79-4131-85f2-f1844709d042 --body '{"_id":"3fc7ce22-fc79-4131-85f2-f1844709d042","_type":{"_id":"DataStoreDecisionNode","name":"Data Store Decision"}}' ===> { "_rev": "756753534", "_type": { "_id": "DataStoreDecisionNode", "name": "Data Store Decision", "collection": true }, "_id": "3fc7ce22-fc79-4131-85f2-f1844709d042" }
  5. Create the authentication tree with these three nodes, where the UUIDs are the ones you used to create the nodes. Ensure you set entryNodeId to the UUID of the first node and set the outcome of each node to the UUID of the next node. For example: $ create AuthTree --realm employees --id MyNewAuthTree --body '{"entryNodeId":"8f9d2280-caa7-433f-93a9-1f64f4cae60a","nodes":{"8f9d2280-caa7-433f-93a9-1f64f4cae60a":{"displayName":"Username Collector","nodeType":"UsernameCollectorNode","connections":{"outcome":"54f14341-d1b7-436f-b159-d1f9b6c626eb"}},"54f14341-d1b7-436f-b159-d1f9b6c626eb":{"displayName":"Password Collector","nodeType":"PasswordCollectorNode","connections":{"outcome":"3fc7ce22-fc79-4131-85f2-f1844709d042"}},"3fc7ce22-fc79-4131-85f2-f1844709d042":{"displayName":"Data Store Decision","nodeType":"DataStoreDecisionNode","connections":{"false":"e301438c-0bd0-429c-ab0c-66126501069a","true":"70e691a5-1e33-4ac3-a356-e7b6d60d92e0"}}}}' ===> { "entryNodeId":"8f9d2280-caa7-433f-93a9-1f64f4cae60a", "nodes":{ "54f14341-d1b7-436f-b159-d1f9b6c626eb":{ "nodeType":"PasswordCollectorNode", "displayName":"Password Collector", "connections":{ "outcome":"3fc7ce22-fc79-4131-85f2-f1844709d042" } }, "3fc7ce22-fc79-4131-85f2-f1844709d042":{ "nodeType":"DataStoreDecisionNode", "displayName":"Data Store Decision", "connections":{ "false":"e301438c-0bd0-429c-ab0c-66126501069a", "true":"70e691a5-1e33-4ac3-a356-e7b6d60d92e0" } }, "8f9d2280-caa7-433f-93a9-1f64f4cae60a":{ "nodeType":"UsernameCollectorNode", "displayName":"Username Collector", "connections":{ "outcome":"54f14341-d1b7-436f-b159-d1f9b6c626eb" } } }, "_rev":"1365759445", "_id":"MyNewAuthTree" }

See Also

Best practice for migrating Authentication Chains to Trees in AM 6.x

How do I modify the prompt text shown when authenticating to a tree in AM 5.5.x, 6.x and 7.x?

Authentication and Single Sign-On Guide › Configuring Authentication Trees

Entity Reference › UsernameCollector

Entity Reference › PasswordCollector

Entity Reference › DataStoreDecision

Entity Reference › AuthTree

Related Training

N/A

Related Issue Tracker IDs

N/A


Copyright and Trademarks Copyright © 2021 ForgeRock, all rights reserved.