Store values in shared tree state
Tree state exists for the lifetime of the journey session. When the tree has completed, the journey session is terminated and an authenticated session is created. The purpose of tree state is to hold state between the nodes.
A good example is the Username Collector node, which gets the username from the user and stores it in the shared tree state. Later, the Data Store Decision node can pull this value from the shared tree state and use it to authenticate the user.
Authentication trees can be stateful or stateless. When they are stateful, the AM server that starts the authentication flow mustn’t change. A load balancer cookie is set on the responses to the user to ensure the same AM server is used. When they are stateless, any AM instance in a deployment can proceed with the journey session.
You can find more information on configuring sessions in Sessions.
Store values in a tree’s node states
Always store the authentication state in the NodeState
object
that AM lets you access from the TreeContext
object passed to the node’s process()
method.
AM ensures the node state is made available to downstream nodes:
-
Store non-sensitive information with the
NodeState.putShared()
method. -
Store sensitive information, such as passwords, with the
NodeState.putTransient()
method.AM encrypts the transient state with the key that has the
am.authn.trees.transientstate.encryption
secret label. Downstream nodes must have the same key to decrypt and read it.Limit what you store with the
putShared()
andputTransient()
methods to make sure the authentication flow isn’t bloated with calls to encrypt or decrypt data, and the journey session size stays small. This is especially true when the realm is configured for client-side journey sessions.
Get and set values stored in tree state
Internally, AM distinguishes the following node state data:
-
Shared state, where nodes store non-sensitive information that needs to be available during the authentication flow.
You store this with the
NodeState.putShared()
method. -
Transient state, where nodes store sensitive information that AM encrypts on round trips to the client.
You store this with the
NodeState.putTransient()
method. -
Secure state, where nodes store decrypted transient state.
Learn more in NodeState.
Set values in the tree state
To set node state values, get the NodeState
using the TreeContext.getStateFor(Node node)
method.
Then, use the NodeState.putShared()
and NodeState.putTransient()
methods as described above.
For example:
// Setting values in NodeState
public Action process(TreeContext context) {
String username;
String password;
// ...
NodeState state = context.getStateFor(this);
state.putShared(USERNAME, username); // Non-sensitive information
state.putTransient(PASSWORD, password); // Sensitive information
if (!state.isDefined(OPTIONAL_NUMERIC)) { // Check before updating
state.putShared(OPTIONAL_NUMERIC, 42);
}
goToNext().build();
}
Get values in the tree state
To read node state values, use the NodeState.isDefined(String key)
and NodeState.get(String key)
methods.
For example:
// Getting values from NodeState
public Action process(TreeContext context) {
NodeState state = context.getStateFor(this);
String username;
if (state.isDefined(USERNAME)) {
username = state.get(USERNAME);
} else {
throw new NodeProcessException("Username is required");
}
// ...
goToNext().build();
}
The get(String key)
method retrieves the state for the key from NodeState
states in the following order:
-
transient
-
secure
-
shared
For example, if the same property is stored in the transient and shared states, the method returns the value of the property in the transient state first.
Combine objects
To combine objects from shared, transient and secure state, use the getObject
method.
For example, if the following objectAttributes
value exists in shared state:
"objectAttributes": { "sharedKey": "value" }
and the following objectAttributes
value exists in transient state:
"objectAttributes": { "transientKey": "value" }
when you call nodeState.getObject("objectAttributes");
, the combined result is as follows:
{
"sharedKey": "value",
"transientKey": "value"
}
This object is read-only.
Merge keys
To merge keys in an object, use the mergeShared
and mergeTransient
methods.
Learn more in Access shared state data.