IBM Security Verify

 View Only

Storing Data Across Multiple Authentication Policies, or How to create Magic Links using ISAM

By Philipp Klueter posted Fri July 05, 2019 12:46 AM



The use of passwords as login credentials gets more and more uncommon. The vast number of passwords a user needs to remember leads to either less complex and more predictable passwords or in case of complex passwords policies to writing it down or reusing it across multiple services. One alternative solution which emerged in recent years, is the use of magic links to provide a password free login. Instead of asking for the password, a link is sent to the user's email address which subsequently can be used to log in. 

The Challenge

In ISAM, such extended authentication processes are implemented using the Authentication Policy feature. This feature provides a flexible way to create workflows, such as the mentioned login flows or user selfcare services. Though, the feature is not designed for interruptions during a workflow. However, such an interruption occurs when using magic links where the link can be opened in a different session or even in another browser. 

The Solution

A simple solution for this issue is to split-up the process into two independent workflows:

  1. The process of sending the email including the magic link.
  2. The process of validating the magic link and logging the user in.

To be able to create these two workflows, the sharing of data across them is necessary.

In the following, I show how the IDMappingExtCache can be used to provide the above described feature.

How It Is Done

Sending the Magic Link

First, let's start with the sending of the magic link.

The authentication policy consists of 4 authentication mechanisms:

  1. A HTML page where the user is requested for his email address.
  2. A pure JavaScript Infomap mechanism to create a unique link for the user.
  3. An email mechanism for sending the link.
  4. A success page to provide feedback to the user.


The first authentication mechanism looks for an incoming email address as well as a targetURL parameter. The targetURL is used to redirect the user to the correct resource after the second workflow is completed. If the email address is present, the value is checked against the user registry. If a user is found, the process continues, otherwise, the corresponding HTML page of the authentication mechanism is shown.

The JavaScript file of the second authentication mechanism contains the required logic. The generateNonce() function creates a unique identifier for mapping the incoming request of the second workflow to the stored user data. The following lines of code store the username using the nonce for a defined time frame (in this case 10 minutes) and build the required verification link.

The lifetime of the cache entry defines the lifetime of the magic link. As soon as the entry is deleted form the cache, the magic link becomes invalid.

The last line stores the link in such way into the session, that it can be used inside the email template.


 * Define Cache to simplify the mapping rules
var cache = IDMappingExtUtils.getIDMappingExtCache()


 * Store the uid under the nonce. W can retreive it when the link is clicked.
 * Also store the Target URL to ensure the redirect is correct.
cache.put(nonce, uid, sessionLifetime);
cache.put(nonce + "_targetURL", targetURL, sessionLifetime);

IDMappingExtUtils.traceString("Stored uid: '" + uid + "' under nonce: '" + nonce + " ' for Lifetime: " + sessionLifetime)

 * Create URL including the nonce
 * Note: The hostname is set in the Utility JS, so it's always available when the script is included
var magicLinkId = "magiclink"
var link = "https://" + hostname + "/mga/sps/authsvc/policy/" + magicLinkId * "?nonce=" + nonce;

//Set required attributes for email message
context.set(Scope.SESSION, "urn:ibm:security:asf:response:token:attributes", "uid", uid);
context.set(Scope.SESSION, "urn:ibm:security:asf:response:token:attributes", "email", email);
context.set(Scope.SESSION, "urn:ibm:security:asf:response:token:attributes", "link", link); 

The next two authentication mechanisms are basic. You can find the email template as well as the HTML page and JavaScript rule for the success page in the GitHub repository at

Verifying the Verification Link

The second workflow contains of a single authentication mechanism:

  1. A pure JavaScript Infomap mechanism to verify the verification link, load the user data and create the ISAM session


The following lines show how to verify the existence of the cache entry as well as how to retrieve and remove it. The removal is required to prevent a second usage of the link.


if (cache.exists(nonce)) {
    var uid = cache.getAndRemove(nonce);
    var targetURL = cache.getAndRemove(nonce + "_targetURL");

After receiving the username, the data is stored into the session response parameters to enable the authentication policy engine to create the required EAI headers.


context.set(Scope.SESSION, "urn:ibm:security:asf:response:token:attributes", "username", uid);
if (targetURL != "none") {
    context.set(Scope.SESSION, "urn:ibm:security:asf:response:token:attributes", "itfim_override_targeturl_attr", targetURL);

This finalizes how the IDMappingExtCache can be used for storing data across authentication polices and how this feature can be used to login a user via a magic link.

Additional Use Case - Reset Password

An additional common use case which can leverage the use of storing data across multiple workflows is a password reset flow. The use of a verification link to authenticate the user is very common in this area. In the GitHub repository you also find the source code for this use case. The following policies must be created:

  • Name: Password Reset
    URI: passwordreset
    Enabled: True
    • Password Reset - Get User
    • Password Reset - Create Link
    • Password Reset - Send Link
    • Password Reset - Send Link Success
  • Name: Password Reset Verification
    URI: passwordresetverify
    Enabled: True
    • Password Reset - Receive Link
    • Password Reset - Collect Password
    • Password Reset - Success

Please note that the JavaScript files were intentionally split up to better show the purpose of the code. Additionally, the files can be easily extended to better serve edge cases or to prevent brute force attacks.

All files are for demonstration purpose only, they should be verified before using in production.