See api-docs Menu

Pre-Authentication

The pre-authentication hook runs synchronously as part of a UI based login flow. The hook fires immediately after the user enters a username/email but before they enter their password or are prompted for multi-factor authentication.

Traditionally in OneLogin, what happens during the login flow is dictated by the User Policy that is assigned to a user. The primary benefit of this hook is that is gives you an opportunity to change the User Policy in real time based on a set of conditions.

For example, You may want to supress MFA registration unless a user is on a trusted network or prompt for stronger MFA factors when a user has a higher risk score or is travelling to a different country.

All of this is possible by creating the policies that represent the desired login behavior and then using the hook function to assign the appropriate policy at login time.

Pre-Authentication Smart Hook

Minimum Viable Function

At a minimum the pre-authentication hook should return a user object containing a policy_id value. The function below is effectively like not having a pre-authentication hook defined at all. It simply takes the user object from context and immediately returns it back to continue a login flow.

exports.handler = async (context) => {
  return {
    success: true,
    user: {
      policy_id: context.user.policy_id
    }
  }
}

This function must be base64 encoded and then is submitted to the create hook endpoint

{
  "type": "pre-authentication",
  "function": "",
  "disabled": false,
  "runtime": "nodejs12.x",
  "retries": 0,
  "timeout": 1,
  "options": {
    "risk_enabled": false,
    "location_enabled": false,
    "mfa_device_info_enabled": true    
  },
  "env_vars": [
  ],
  "packages": {
  },
  "conditions": [
    {
        "source": "roles",
        "operator": "~",
        "value": "123456"
    }
  ]  
}

Where hooks get exciting is when you consider what you might be able to do before returning the user and their associated user policy.

Hook Config Options

There are configuration options are specific to the Pre-Authentication hook. They allow you to control the information that is supplied to in the hook context which is useful for optimizing performance. Generally speaking every piece of context information comes at a cost to deliver so ideally you should only enable the context features that your hook is making of use of.

The following options can be supplied in the options parameter when creating/updating a hook.

risk_enabled

required

boolean

Default false. When true a risk score and risk reasons will be passed in the context. Only applies authentication time hooks. E.g. pre-authentication.

mfa_device_info_enabled

optional

boolean

Default false. When true a list of MFA devices registered by the user will be made available in the pre-authentication context.

location_enabled

required

boolean

Default false. When true an ip to location lookup is done and the location info is passed in the context. Only applies authentication time hooks. E.g. pre-authentication.

Hook Context

A context object is passed into every hook function. The context contains information about the user and device as well as optional information about their current risk score and location.

To enable the continuous improvements and upgrades the context is versioned. With each version of the context some attributes may be added or removed so you should always check to see that your Smart Hook still functions as expected if you change the context version.

When creating a new pre-authentication hook the latest version of the context will be used. You can use prior context versions by specifying the context_version attribute in your Smart Hook config.

Version 1.0.0

{
  "user": {
    "user_identifier": "jim-hendrix",
    "policy_id": 187345 
  },
  "device": {
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
    "is_mobile": false
  },
  "location": {
    "ip": "120.118.218.225",
    "country_code": "TW"
  },
  "risk": {
    "score": 30,
    "reasons": [
      "Infrequent access from 120.118.218.225",
      "Infrequent access from Kaohsiung City, Kaohsiung, Taiwan",
      "Infrequent access from Taiwan",
      "Infrequent access using Chrome on Windows",
      "Low trust for session"
    ]
  }, 
  "correlation_id": "13a97251-215d-4fa5-baaf-6fc15700a2db",
  "request_id": "7d436b7e-b4a3-4b48-83fd-f4a12c22bb62"
}

Version 1.1.0

{
  "user": {
    "user_identifier": "jim-hendrix",
    "policy_id": 187345,
    "id": 36216766,
    "last_login_success": "2020-10-21T17:04:22.852Z",    
  },
  "device": {
    "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36",
    "is_mobile": false
  },
  "location": {
    "ip": "120.118.218.225",
    "country_code": "TW"
  },
  "risk": {
    "score": 30,
    "reasons": [
      "Infrequent access from 120.118.218.225",
      "Infrequent access from Kaohsiung City, Kaohsiung, Taiwan",
      "Infrequent access from Taiwan",
      "Infrequent access using Chrome on Windows",
      "Low trust for session"
    ]
  },
  "mfa_devices": [
    {
      "auth_factor_id" 16885,
      "device_id" 1825100,
      "user_display_name" "Google Authenticator",
      "type_display_name" "Google Authenticator",
      "auth_factor_name": "Google Authenticator",
      "default": true,
      "last_used_at": "2020-10-20T12:33:24.266Z",
      "created_at": "2020-03-02T14:53:00.445Z"
    }
  ],
  "app": {,
    "id: 959314,
    "uuid": "1a650385-d500-42e3-921e-14aa4020ae70",
    "name": "OIDC - PKCE",
  },  
  "correlation_id": "13a97251-215d-4fa5-baaf-6fc15700a2db",
  "request_id": "7d436b7e-b4a3-4b48-83fd-f4a12c22bb62"
}

Context Attributes

user An object that represents the user attempting to authenticate.
  • user_identifier - The username or email address entered by the user.
  • policy_id - The User Policy that will be applied for the rest of the login flow.
  • id - The users unique ID in OneLogin.
  • last_login_success - The ISO8601 date of the users last successful authentication.
device An object describing the device used during the authentication.
  • user_agent - The authenticating users browser or user agent.
  • is_mobile - A boolean flag that indicates if the login is taking place on a mobile device
location An object describing the location of the authenticating user. This is only populated if the location_enabled property is set to true when creating/updating the Hook function.
  • ip - The authenticating users ip address.
  • country_code - An ISO 3166 Aplha 2 character country code based on a geo ip address lookup.
risk An object representing the current risk score for the authenticating user. This is only populated if the risk_enabled property is set to true when creating/updating the Hook function.
  • score - An integer between 0 (low) - 100 (high) risk level.
  • reasons - An array of strings that indicate the primary drivers behind the risk score.
mfa_devices An object representing the mfa devices that are registered for the authenticating user. This is only populated if the mfa_device_info_enabled property is set to true when creating/updating the Hook function.
app An object representing the app that initiated the authentication. This attribute will be null for authentications that are not SP initiated.
correlation_id A unique identifier that can be used to trace a transaction end to end. This is useful if you need help from OneLogin support in debugging any issues.
request_id A unique identifier that can be used to trace a single incoming request.

Hook Response

The Pre-authentication hook gives you the opportunity to change the User Policy that will be used for the rest of the login flow (it does not permanently change their assigned User Policy). Therefore the minimum required response for this hook is a user object containing the policy id.

For example, This function will do nothing and keep the User Policy set to the users currently allocated policy.

exports.handler = async (context) => {
  return {
    success: true,
    user: {
      policy_id: context.user.policy_id
    }
  }
}

Where as this hook function would change the User Policy for mobile device users

exports.handler = async (context) => {
  
  let user = context.user;

  if (context.device.is_mobile) {
    user.policy_id = 1234;
  }

  return {
    success: true,
    user: user
  }
}

You can also halt the login flow and therefore deny the user the ability to complete the login by returning success: false from the function.

For example, Deny access based on high risk

exports.handler = async (context) => {
  
  // Deny on high risk
  if (context.risk.score > 90) return { success: false, user: null }

  // Otherwise let them login as normal
  return {
    success: true,
    user: context.user
  }
}

Conditions

By default the Pre-Authentication Smart Hook will be executed for every UI based login. Conditions are an attribute the Smart Hook config that let you limit the number of users impacted by the hook via the use of Roles. This is particularly useful when developing and testing your hook but can also be used to further customize conditional access workflows.

For example, you might have thousands of users authenticating daily so you want to be careful when introducing a new hook. Rather than have the hook execute for every user login you could create a role called “Experimental Smart Hook Users” and then have the hook only trigger for users that are assigned to that role.

{
  "type": "pre-authentication",
  "conditions": [
    {
        "source": "roles",
        "operator": "~",
        "value": "123456"
    }
  ]
}
source Must be set to roles.
operator
  • ~ The user Must be in this role
  • !~ The user Must Not be in this role.
value The role_id to match on.

Postman Collection

We’ve created a library of sample Hook functions in the Postman collection. We will keep it updated with functions that solve common requested workflows.

Postman Pre Request Script

To view & modify the function click on the Pre Request Script tab within Postman. Also note that this script will Base64 encode the function before it sends it to the Smart Hooks API.

Download for the Smart Hooks API