Authentication nodes and trees
Authentication trees (also referred to as Intelligent Authentication) provide fine-grained authentication by allowing multiple paths and decision points throughout the authentication flow. Use them to build complex authorization scenarios, while offering users a streamlined sign-on experience.
Authentication trees are made up of authentication nodes, which define actions taken during authentication. Each node performs a single task during authentication, such as, collecting a username or making a simple decision based on a cookie.
Nodes can have multiple outcomes rather than just success or failure. This allows you to create complex yet customer-friendly authentication experiences by linking nodes together, creating loops, branching the tree for different authentication scenarios, and nesting nodes within a tree:
To further control the authentication process, you can assign authentication levels to branches on a tree, with higher levels being used typically to allow access to more restricted resources.
Authentication trees differ in the following ways from traditional authentication chains:
-
Authentication trees can’t mix with authentication chains. Each authentication to AM can use either a tree or a chain, but not both together.
-
The functionality derived from post-authentication plugins, used traditionally with authentication chains, is handled differently when using trees. For example:
-
Session property management is handled by individual nodes. Learn more in Set Session Properties node.
-
Calling out to third-party systems is handled by scripted nodes. Learn more in Scripted Decision node.
-
Registering events to make HTTP POST calls to a server is handled by webhooks. Learn more in Configure authentication webhooks. Post-authentication plugins don’t get triggered when authenticating to a tree, only to a chain.
-
Authentication levels for trees
When a user successfully authenticates, AM creates a session, which allows AM to manage the user’s access to resources. The session is assigned an authentication level. The authentication level is often used as a measure of the strength of the authentication performed. For example, username and password could be assigned a low authentication level, and multi-factor with Push and webAuthn could be assigned a high one.
Authorization policies could require a particular authentication level to access protected resources. When an authenticated user tries to access a protected resource without satisfying the authentication level requirement, AM denies access to the resource and returns an advice indicating that the user needs to reauthenticate at the required authentication level to access the resource.
The web or Java agent or policy enforcement point can then send the user back to AM for session upgrade. Learn more in Session upgrade
AM provides the following nodes to manage authentication levels:
-
The
Authentication Level Decision
node, which checks if the current authentication level is equal or greater than the one specified in the node. -
The
Modify Authentication Level
node, which can raise or lower the authentication level.
Position these nodes to alter the authentication level depending on the route taken through the authentication tree.
Account lockout for trees
Use account lockout to limit the number of times an end user can attempt to authenticate with invalid credentials before rendering their account inactive. Limiting the number of attempts helps to prevent password-guessing and brute-force attacks.
By default, authentication trees support account lockout and provide nodes for checking and changing a user’s status:
- Account Active Decision node
-
Use this node to determine whether an account is locked or unlocked.
-
An account is considered locked under these conditions:
-
The status is
inactive
. -
The status is
active
and a duration lockout is set on the account.
-
-
An account is considered unlocked under this condition:
-
The status is
active
and no duration lockout is set on the account.
-
-
- Account Lockout node
-
Use this node to change the account’s status to inactive or active.
When setting an account to inactive, the node doesn’t consider the realm’s account lockout settings, so effectively sets a persistent lockout on the account.
When setting an account to active, the node also resets the failed attempts and lockout duration counters.
In addition to the lockout-specific nodes above, the Success and Failure nodes include account lockout functionality, when lockout is enabled in a realm, as follows:
- Success node
-
-
Checks the User Status property of the user profile, when reached, and fails the authentication with an error message, if the account is marked as
Inactive
:The error message is returned in the JSON response if authenticating to the tree by using REST:
{ "code":401, "reason":"Unauthorized", "message":"User Locked Out." }
-
Resets the failure count in the user profile, when reached, if the User Status property is set to
Active
.
-
- Failure node
-
-
Checks the invalid attempts property of the user profile, and returns a warning message if the number of failed attempts is equal to or greater than the configured Warn User After N Failures value in the realm:
The error message is returned in the JSON response if authenticating to the tree by using REST:
{ "code":401, "reason":"Unauthorized", "message":"Warning: You will be locked out after 1 more failure(s)." }
-
Increments the failure count in the user profile, when reached.
-
Returns an error message if the account is marked as
Inactive
:The error message is returned in the JSON response if authenticating to the tree by using REST:
{ "code":401, "reason":"Unauthorized", "message":"User Locked Out." }
-
You can find information on configuring account lockout in a realm in Account lockout.
Specify IDM identity resources in trees
When running AM as part of an integrated platform with IDM,
trees configured to use the platform need to identify
the type of identity resource or object the tree is working with.
To do this, use the identityResource
configuration property.
If the property isn’t included in the tree configuration, it defaults to managed/user
.
To update identityResource
on a tree, use the REST API to update the tree:
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId":"e301438c-0bd0-429c-ab0c-66126501069a",
"nodes":{},
"staticNodes":{},
"description":"Example tree description",
"identityResource":"managed/newObjectType"
}' \
"https://openam.example.com:8443/openam/json/realms/root/realm-config/authentication/authenticationtrees/trees/ExampleTree"
In the previous example, the tree ExampleTree
has no nodes added to it yet.
It includes the identityResource
property, set to use a managed object in IDM called newObjectType
.
Because this is a PUT
request, you must include the entire tree as part of the request.
You can find more information about using the REST API in REST in AM.
Configure authentication trees
The following table summarizes the high-level tasks required to configure authentication trees:
Task | Resources | ||
---|---|---|---|
Design your user authentication journey Authentication trees are flexible. For example, the same tree can branch for different use cases, or users can be forced to loop though branches until they’re able to present the required credentials. It’s easy to create a massive tree that’s difficult to understand, read, and maintain in the UI. For this reason, AM lets you nest trees within trees. The best way to tackle the design decision is to write down a list of required steps users would need to take to sign on to your environment. Then, check the list of nodes available in AM.
|
|
||
Decide if you need custom authentication nodes and webhooks If the nodes available in AM or in the Marketplace don’t meet your needs, you can build your own nodes. In the same way, you can create custom webhooks for nodes that need them. |
|||
Configure your authentication trees Use the authentication tree designer to put together your trees quickly. |
|||
Configure webhooks, if required If you have configured the |
Create an authentication tree in the UI
-
In the AM admin UI, go to Realms > Realm Name > Authentication > Trees and click Create Tree.
-
Enter a tree name, for example
myAuthTree
, and click Create.The authentication tree designer displays with the Start entry point connected to the Failure exit point.
The authentication tree designer provides the following features on the toolbar:
Authentication tree designer toolbar Button Usage Lay out and align nodes according to the order they’re connected.
Toggle the designer window between normal and full screen layout.
Remove the selected node. You can’t delete the Start entry point.
-
Add a node to the tree by dragging the node from the Components panel on the left-hand side, and dropping it into the designer area.
The list of authentication nodes is divided into categories. Click the category title to expand and collapse the categories.
Use the filter text field to restrict the list of authentication nodes. This will match on the node’s name and any tags applied to the node:
-
Configure the node properties by using the right-hand panel.
You can find more information on the available properties for each node in Authentication nodes configuration reference.
-
Connect the node to the tree as follows:
-
Select and drag the output connector from an existing node and drop it onto the new node.
-
Select and drag the output connector from the new node and drop it onto an existing node.
Nodes have one or more connectors, displayed as dots on the node. Unconnected connectors appear red until you connect them to other nodes in the tree.
Input connectors appear on the left of the node, output connectors appear on the right. A line is drawn between the connectors of connected nodes, and the connectors no longer appear red.
-
-
To change a connection, select and drag the green connector in the connection and drop it onto the new location.
-
Continue adding, connecting and removing nodes until the tree is complete, then click Save.
-
Test your authentication tree by navigating to a URL similar to the following:
https://openam.example.com:8443/openam/XUI/?realm=/alpha&service=myAuthTree#login
Create an authentication tree over REST
To create an authentication tree over REST, send individual PUT requests to create each node. Then send a PUT request to update the tree configuration, including the tree ID and all the nodes in the tree. You can find information on the required parameters in the online REST API reference.
Consider the following when creating authentication trees using the REST API:
-
You must re-create each node when creating a new authentication tree.
-
Each node must have a valid UUID as its identifier. You can generate UUIDs online, for example, using the Online UUID Generator.
If you don’t use a valid UUID, authentication will fail with the following error:
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. This allows you to move between nodes. -
The Success and Failure nodes have the following static UUIDs:
-
Success node:
70e691a5-1e33-4ac3-a356-e7b6d60d92e0
-
Failure node:
e301438c-0bd0-429c-ab0c-66126501069a
These UUIDs remain constant across all authentication trees and AM versions.
-
Example
Complete these steps to create a simple authentication tree consisting of three nodes: Username Collector node, Password Collector node, and Data Store Decision node.
-
Generate UUIDs for each of the nodes you want to create. This example uses the following UUIDs:
-
Username Collector node:
8f9d2280-caa7-433f-93a9-1f64f4cae60a
-
Password Collector node:
54f14341-d1b7-436f-b159-d1f9b6c626eb
-
Data Store Decision node:
3fc7ce22-fc79-4131-85f2-f1844709d042
-
-
Authenticate to AM as the
amAdmin
user:$ curl \ --request POST \ --header "Content-Type: application/json" \ --header "X-OpenAM-Username: amadmin" \ --header "X-OpenAM-Password: password" \ --header "Accept-API-Version: resource=2.0, protocol=1.0" \ 'https://openam.example.com:8443/openam/json/realms/root/realms/alpha/authenticate' { "tokenId":"AQIC5wM…TU3OQ*", "successUrl":"/am/console", "realm":"/alpha" }
-
Create the Username Collector node, where the UUID is the one you generated in step 1:
$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "_id": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "_type": { "_id": "UsernameCollectorNode", "name": "Username Collector" } }' \ "https://openam.example.com:8443/openam/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/UsernameCollectorNode/8f9d2280-caa7-433f-93a9-1f64f4cae60a" { "_id": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "_rev": "280717409", "_type": { "_id": "UsernameCollectorNode", "name": "Username Collector", "collection": true }, "_outcomes": [ { "id": "outcome", "displayName": "Outcome" } ] }
-
Create the Password Collector node, where the UUID is the one you generated in step 1:
$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "_id": "54f14341-d1b7-436f-b159-d1f9b6c626eb", "_type": { "_id": "PasswordCollectorNode", "name": "Password Collector" } }' \ "https://openam.example.com:8443/openam/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/PasswordCollectorNode/54f14341-d1b7-436f-b159-d1f9b6c626eb" { "_id": "54f14341-d1b7-436f-b159-d1f9b6c626eb", "_rev": "792175357", "_type": { "_id": "PasswordCollectorNode", "name": "Password Collector", "collection": true }, "_outcomes": [ { "id": "outcome", "displayName": "Outcome" } ] }
-
Create the Data Store Decision node, where the UUID is the one you generated in step 1:
$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "_id": "3fc7ce22-fc79-4131-85f2-f1844709d042", "_type": { "_id": "DataStoreDecisionNode", "name": "Data Store Decision" } }' \ "https://openam.example.com:8443/openam/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/nodes/DataStoreDecisionNode/3fc7ce22-fc79-4131-85f2-f1844709d042" { "_id": "3fc7ce22-fc79-4131-85f2-f1844709d042", "_rev": "2145625368", "_type": { "_id": "DataStoreDecisionNode", "name": "Data Store Decision", "collection": true }, "_outcomes": [ { "id": "true", "displayName": "True" }, { "id": "false", "displayName": "False" } ] }
-
Create the authentication tree with these three nodes, where the UUIDs are the ones you used to create the nodes. Make sure you set
entryNodeId
to the UUID of the first node and set theoutcome
of each node to the UUID of the next node:$ curl \ --request PUT \ --header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \ --header "Content-Type: application/json" \ --header "Accept-API-Version: protocol=2.1,resource=1.0" \ --header "If-None-Match: *" \ --data '{ "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" } } } }' \ "https://openam.example.com:8443/openam/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myNewTree" { "_id": "myNewTree", "_rev": "2061817222", "uiConfig": {}, "entryNodeId": "8f9d2280-caa7-433f-93a9-1f64f4cae60a", "innerTreeOnly": false, "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" } } }, "enabled": true }
-
Verify the tree has been created in the AM admin UI. It should look similar to this:
Enable and disable an authentication tree
Custom authentication trees are enabled by default when you save them. For security purposes, you can disable custom authentication trees during development and testing to prevent accidentally allowing access through these trees. Rather than having unused authentication trees enabled, you should disable the default authentication trees until you need them.
When a user attempts to authenticate through a disabled tree, AM returns a No configuration found
error.
To enable or disable an authentication tree, send a PUT request to update the tree configuration. Include the tree ID
and all the nodes in the tree, and set the enabled
property.
You can find information on the required parameters in the
online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
"c11e9cf8-ef48-4740-876f-6300e2f46aef": {
"displayName": "Page Node",
"nodeType": "PageNode",
"x": 147,
"y": 25,
"connections": {
"outcome": "15839e1c-5085-4f58-bc94-c4cc848a0ae8"
}
},
"15839e1c-5085-4f58-bc94-c4cc848a0ae8": {
"displayName": "Data Store Decision",
"nodeType": "DataStoreDecisionNode",
"x": 349,
"y": 25,
"connections": {
"true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0",
"false": "e301438c-0bd0-429c-ab0c-66126501069a"
}
}
},
"enabled": false
}' \
"https://openam.example.com:8443/openam/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "2070284866",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
"c11e9cf8-ef48-4740-876f-6300e2f46aef": {
"displayName": "Page Node",
"nodeType": "PageNode",
"x": 147,
"y": 25,
"connections": {
"outcome": "15839e1c-5085-4f58-bc94-c4cc848a0ae8"
}
},
"15839e1c-5085-4f58-bc94-c4cc848a0ae8": {
"displayName": "Data Store Decision",
"nodeType": "DataStoreDecisionNode",
"x": 349,
"y": 25,
"connections": {
"true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0",
"false": "e301438c-0bd0-429c-ab0c-66126501069a"
}
}
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"innerTreeOnly": false,
"enabled": false
}
Disable direct access through an inner tree
An inner tree or child tree lets you nest authentication logic. There is no limit to the depth of nesting.
You configure an inner tree like any other tree then call it from a parent tree using an Inner Tree Evaluator node.
You could want to hide inner trees as complete services. In other words, you could want to prevent users from authenticating directly through an inner tree, either for security reasons or because the inner tree is insufficient as a complete authentication service.
To prevent a tree from being used outside of its parent tree, set the innerTreeOnly
property to true
in the tree
configuration. Send a PUT request to update the tree configuration, including the tree ID and all the nodes in the tree.
You can find information on the required parameters in the
online REST API reference.
Example
$ curl \
--request PUT \
--header "iPlanetDirectoryPro: AQIC5wM…TU3OQ*" \
--header "Content-Type: application/json" \
--header "Accept-API-Version: protocol=2.1,resource=1.0" \
--header "If-None-Match: *" \
--data '{
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"nodes": {
"c11e9cf8-ef48-4740-876f-6300e2f46aef": {
"displayName": "Page Node",
"nodeType": "PageNode",
"x": 147,
"y": 25,
"connections": {
"outcome": "15839e1c-5085-4f58-bc94-c4cc848a0ae8"
}
},
"15839e1c-5085-4f58-bc94-c4cc848a0ae8": {
"displayName": "Data Store Decision",
"nodeType": "DataStoreDecisionNode",
"x": 349,
"y": 25,
"connections": {
"true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0",
"false": "e301438c-0bd0-429c-ab0c-66126501069a"
}
}
},
"innerTreeOnly": true
}' \
"https://openam.example.com:8443/openam/json/realms/root/realms/alpha/realm-config/authentication/authenticationtrees/trees/myAuthTree"
{
"_id": "myAuthTree",
"_rev": "1081620278",
"uiConfig": {},
"entryNodeId": "c11e9cf8-ef48-4740-876f-6300e2f46aef",
"innerTreeOnly": true,
"nodes": {
"c11e9cf8-ef48-4740-876f-6300e2f46aef": {
"displayName": "Page Node",
"nodeType": "PageNode",
"x": 147,
"y": 25,
"connections": {
"outcome": "15839e1c-5085-4f58-bc94-c4cc848a0ae8"
}
},
"15839e1c-5085-4f58-bc94-c4cc848a0ae8": {
"displayName": "Data Store Decision",
"nodeType": "DataStoreDecisionNode",
"x": 349,
"y": 25,
"connections": {
"true": "70e691a5-1e33-4ac3-a356-e7b6d60d92e0",
"false": "e301438c-0bd0-429c-ab0c-66126501069a"
}
}
},
"staticNodes": {
"startNode": {
"x": 50,
"y": 25
},
"70e691a5-1e33-4ac3-a356-e7b6d60d92e0": {
"x": 570,
"y": 30
},
"e301438c-0bd0-429c-ab0c-66126501069a": {
"x": 573,
"y": 107
}
},
"enabled": true
}
Configure authentication webhooks
Webhooks are used to send HTTP POST calls to a server with contextual information about an authentication session when a predefined event occurs, for example, logging out.
Webhooks are used from within authentication trees by the Register Logout Webhook node.
Create a webhook
-
In the AM admin UI, go to Realms > Realm Name > Authentication > Webhooks.
-
To create a new webhook, select Create Webhook, specify a webhook name, and click Create.
-
To edit an existing webhook, select the name of the webhook.
-
-
Complete the fields as required:
- Url
-
Specifies the URL to which the HTTP POST is sent when the event occurs.
- Body
-
Specifies the body of the HTTP POST. You can send different formats by also setting the correct Content-Type header in the
Header
property, for example:-
Form Data. Enter the body value in the format
parameter=value¶meter2=value2
, and set aContent-Type
header ofapplication/x-www-form-urlencoded
. -
JSON Data. Enter the body value in the format
{"parameter":"value","parameter2":"value2"}
, and set aContent-Type
header ofapplication/json
.
-
- Headers
-
Specifies any HTTP headers to add to the POST.
To add a header, enter the name of the header in the
Key
field, and the value, and click Add (➕).To remove a header, click Delete (✖).
The fields in a webhook support variables for retrieving values from the user’s session after successfully authenticating.
Specify a variable in the following format:
${variable_name}
To access the type of webhook event, use the
WebhookEventType
parameter key to return one of the following possible values:-
LOGOUT
-
UPGRADE
-
DESTROY
-
MAX_TIMEOUT
-
IDLE_TIMEOUT
For example, to retrieve the event type as a query parameter:
&event=${WebhookEventType}
You can use a variable to access custom properties added to the session with the Set Session Properties node as well as the following default session properties:
Default Session Properties
Property Example value Description AMCtxId
22e73c81-708e-4849-b064-db29b68ef943-105372
The audit ID for the session. This is logged as the
trackingIds
field in AM access audit logs.amlbcookie
01
The cookie that identifies the AM server that generated the session. For environments with multiple AM servers, this can be used for load balancer stickiness.
authInstant
2022-02-28T14:06:31Z
The exact time that authentication completed.
AuthLevel
5
The authentication level of the session, determined by the login mechanism used to create the session. For example, a tree can have an authentication level of 10.
Step-up authentication is triggered if an authentication level specified by an agent or policy that is designed to protect a resource, is greater than or equal to the value of the
AuthLevel
session property.For more information, see Session upgrade.
AuthType
DataStore
A pipe-separated list of modules to which the user has authenticated. For example,
module1|module2|module3
(authentication chains only).CharSet
UTF-8
The character set for the session, set to
UTF-8
.clientType
genericHTML
The type of client, set to
genericHTML
.FullLoginURL
/openam/XUI/?realm=%2Falpha
The full login URL, including query parameters.
Host
192.0.2.1
The originating IP address of the authentication request (authentication trees only).
HostName
192.0.2.1
The host name that was used when the session was authenticated.
IndexType
service
Based on the value of the
authIndexValue
query parameter during authentication. Typically, this is set toservice
.Locale
en_US
The session locale.
loginURL
/openam/XUI
The base login URL. A subset of
FullLoginURL
.OidcSid
g0wmSpoAIwH6HAwCnurvRcfYqh4
Unique session ID used by AM to determine whether OIDC ID tokens granted for the same client relate to the same session. This appears when
Enable Session Management
(storeOpsToken
) is set to true in the OAuth 2.0 provider settings.Organization
o=alpha,ou=services,dc=openam,dc=forgerock,dc=org
The DN of the realm where authentication took place.
Principal
id=demo,ou=user,o=alpha,ou=services,dc=openam,dc=forgerock,dc=org
The value of
sun.am.UniversalIdentifier
.Principals
demo
The username of the user. For multiple principals, this can be a pipe-separated list (authentication chains only).
Service
ldapService
The name of the tree or chain that was used to authenticate this session.
successURL
/openam/console
The URL that was redirected to, upon a successful login request.
sun.am.UniversalIdentifier
id=demo,ou=user,o=alpha,ou=services,dc=openam,dc=forgerock,dc=org
The DN of the user (username is lowercase).
UserId
demo
The
id
value from thePrincipal
property.UserProfile
Required
Can be one of:
Required
,Create
,Ignore
, orCreateWithAlias
. Based on the value of thedynamicProfileCreation
authentication configuration. Values other thanIgnore
indicates that user profile attributes were mapped based on theUser Attribute Mapping to Session Attribute
setting. See authentication configuration for details.Default:
Required
.UserToken
demo
The username, as defined in the
Principals
property. For authentication chains, this is the last principal value.XUSRef
8700f1a5-904e-4849-8b2b-cb25296ef453-291173
If the cross-upgrade session reference property is enabled, this value identifies the session through its lifecycle. This is logged in the
trackingIds
field in AM audit logs for session creation and upgrade events.
Customize authentication trees
Your deployment might require customizing standard authentication trees.
Learn more in Node development.
Create post-authentication hooks for trees
This section explains how to create a hook used by a node within an authentication tree. These tree hooks can perform custom processing after an authentication tree has successfully completed, and a session has been created.
AM includes the following authentication tree hooks:
CreatePersistentCookieTreeHook
-
Used by the Set Persistent Cookie node.
UpdatePersistentCookieTreeHook
-
Used by the Persistent Cookie Decision node.
The core class of an authentication tree hook
The following example shows an excerpt from the UpdatePersistentCookieTreehook
class.
The Persistent Cookie Decision node uses this tree hook to recreate the persistent cookie.
/**
* A TreeHook for updating a persistent cookie.
*/
@TreeHook.Metadata(configClass = PersistentCookieDecisionNode.Config.class) (1)
public class UpdatePersistentCookieTreeHook implements TreeHook { (2)
...
@Inject (3)
public UpdatePersistentCookieTreeHook(@Assisted Request request, @Assisted Response response,
@Assisted PersistentCookieDecisionNode.Config config, @Assisted Realm realm,
PersistentJwtStringSupplier persistentJwtStringSupplier,
PersistentCookieResponseHandler persistentCookieResponseHandler,
PersistentJwtProvider persistentJwtProvider,
@Named("validSecrets") SecretsRetrievalService validSecretsRetrievalService,
NamedSecretsRetrievalService namedSecretsRetrievalService) {
this.request = request;
this.response = response;
this.config = config;
this.persistentJwtProvider = persistentJwtProvider;
this.persistentJwtStringSupplier = persistentJwtStringSupplier;
this.persistentCookieResponseHandler = persistentCookieResponseHandler;
this.realm = realm;
this.validSecretsRetrievalService = validSecretsRetrievalService;
this.namedSecretsRetrievalService = namedSecretsRetrievalService;
}
@Override
public void accept() throws TreeHookException { (4)
logger.debug("UpdatePersistentCookieTreeHook.accept");
String orgName = PersistentCookieResponseHandler.getOrgName(response);
Cookie originalJwt = getJwtCookie(request, config.persistentCookieName());
if (originalJwt != null) {
...
}
}
...
}
1 | The @TreeHook.Metadata annotation.
Before defining the core class, use a Java @TreeHook.Metadata annotation
to specify the class the tree hook uses for its configuration.
Use the configClass property to specify the configuration class of the node that will be using the tree hook.
|
||
2 | The core class must implement the TreeHook interface.
For more information, refer to the TreeHook interface in the AM Public API Javadoc. |
||
3 | AM uses Google’s Guice dependency injection framework for authentication nodes and tree hooks.
Use the @Inject annotation to construct a new instance of the tree hook,
specifying the configuration interface set up earlier and any other required parameters.
For more information, refer to the
Inject annotation type
and the Assisted annotation type
in the Google Guice Javadoc. |
||
4 | Implement the public void accept() method to define actions to perform on a successful journey outcome.
Optionally, override the The main logic of a tree hook is handled by these two methods. |