Differentiate User Logins From Session Reuse (SSO) in Post-Login Actions
A post-login action may require performing distinct logic if it executes as part of a user authentication transaction that includes the user login stage, and skip that logic when the presence of a valid authentication session allows the authentication to proceed without triggering the login prompt.
When an authentication transaction includes the login stage, it means the service verifies the end-user's first-factor authentication, whether password-based, passkeys, or responses from external identity providers.
For example, for a password-based user account, the action requires a specific branch to execute only if the user has submitted credentials as part of the authentication request that triggered the action. It skips that branch if an authenticated session allows single sign-on (SSO), in which case the user does not have to provide password credentials.
- Actions
The recommended approach to distinguish between these two types of authentication transactions is the use of the session information context. However, this context is only available to enterprise subscriptions; for non-enterprise subscriptions, consider the second option.
Remember that post-login actions may execute for a wide range of authentication flows/protocols; see the event.transaction.protocol documentation for additional information. As such, use the options listed below in conjunction with additional checks that further constrain action execution to the relevant situations.
Option 1 (RECOMMENDED) - Using session information:
By comparing the session authenticated timestamp (event.session.authenticated_at) to the session update timestamp (event.session.updated_at), it is possible to determine that a login stage occurred as part of the session update that preceded the execution of actions.
// code snippet for illustration purposes only; lacks additional checks
// for example, verifying that event.session is available
if (event.session.authenticated_at === event.session.updated_at) {
// this authentication transaction included the login stage
}
It is essential to note that this approach is only valid when used in post-login actions that execute before performing an action-based redirect. Resuming the redirect refreshes the session update timestamp, causing the condition to evaluate to false in actions executed after the redirect.
Option 2 - Using authentication methods information:
Verify that the timestamp associated with the chosen authentication method(s) is sufficiently recent. For example, suppose the timestamp associated with the pwd authentication method is within 30 seconds of the current time. In that case, it may be reasonable to assume that the login stage associated with the chosen authentication method occurred as part of the authentication transaction that triggered the action.
// code snippet for illustration purposes only; may require checking
// other authentication method types
const method = event.authentication?.methods.find(
(method) => method.name === "pwd");
if (method) {
// check method.timestamp
}
Given that the approach requires defining an acceptable threshold for comparison purposes, it does not guarantee that a login stage occurred specifically as part of the transaction for which the action executes.