# Extension + PingFederate Integration Guide

## System Requirements

* For Twosense to work properly, service providers must be configured to receive SAML responses as POST, not GET.

## Introduction

Use this guide to add Twosense MFA to your PingFederate SSO authentication flow. The following configuration steps are required:

* [Create RADIUS Password Credential Validator](#create-radius-password-credential-validator)
* [Create Twosense MFA IdP Adapter](#create-twosense-mfa-idp-adapter)
* [Modify the primary authentication adapter to return the userSid](#modify-the-primary-authentication-adapter-to-return-the-usersid)
* [Modify the primary authentication HTML form](#modify-the-primary-authentication-html-form)
* [Create HTTP Header Authentication Selector](#create-http-header-authentication-selector)
* [Create Authentication Policy](#create-authentication-policy)

## Create RADIUS Password Credential Validator

1. Navigate to **SYSTEM** and select **Password Credential Validators**.
2. Click **Create New Instance**.
3. In the **Type** tab, set the following:
   * *Instance Name*: **Twosense MFA RADIUS PCV**
   * *Instance ID*: **TwosenseMfaRadiusPcv**
   * *Type*: **RADIUS Username Password Credential Validator**
   * Click **Next**.
4. In the **Instance Configuration** tab, click **Add a new row to 'RADIUS Servers'**, and set the following:
   * *Hostname*: **radius.twosense.ai**
   * *Authentication Port*: **{Provided by Twosense}**
   * *Authentication Protocol*: **PAP**
   * *Shared Secret*: **{Provided by Twosense}**
   * Click **Update**.
   * Click **Next**.
5. In the **Extended Contract** tab, click **Next**.
6. Review the **Summary** tab, and click **Save**.

## Create Twosense MFA IdP Adapter

This adapter will be used by the Twosense browser extension to automate MFA requests.

1. Copy the `html.form.twosense.mfa.html` and `html.form.twosense.challenge.html` files from the setup package to your PingFederate instance under `pingfederate/server/default/conf/template/`.
2. Navigate to **AUTHENTICATION** and select **IdP Adapters**.
3. Click **Create New Instance**.
4. In the **Type** tab, set the following:
   * *Instance Name*: **Twosense MFA Form**
   * *Instance ID*: **TwosenseMfaForm**
   * *Type*: **HTML Form IdP Adapter**
   * Click **Next**.
5. In the **IdP Adapter** tab, under **Password Credential Validator Instance**, click **Add a new row to 'Credential Validators'**:
   * Select **Twosense MFA RADIUS PCV**
   * Click **Update**.
   * Set the following fields:
     * *Challenge Retries*: **1**
     * Click **Show Advanced Fields**.
     * *Login Template*: **html.form.twosense.mfa.html**
     * *Login Challenge Template*: **html.form.twosense.challenge.html**
     * *Allow Username Edits During Chaining*: **true**
     * *Fail Authentication on Account Lockout*: **true**
     * Click **Next**.
6. In the **Extended Contract** tab, click **Next**.
7. In the **Adapter Attributes** tab, check the **Pseudonym** checkbox for the **username** attribute, and click **Next**.
8. In the **Adapter Contract Mapping** tab, click **Configure Adapter Contract**.
   1. In the **Attribute Sources & User Lookup** tab, click **Next**.
   2. In the **Adapter Contract Fulfillment** tab, click **Next**.
   3. In the **Issuance Criteria** tab, click **Next**.
   4. In the **Summary** tab, click **Done**.
   5. Click **Next**.
9. Review the **Summary** tab, and click **Save**.

## Modify the primary authentication adapter to return the userSid

The Twosense MFA adapter requires the user's `objectSid` attribute. In order to do this, we need to extend the contract of the primary login form IdP adapter.

1. Navigate to **AUTHENTICATION** and select **IdP Adapters**.
2. Click on the IdP adapter of your primary login HTML form.
3. In the **Summary** tab, click **Extend Contract**.
   1. Under **Extend the Contract**, add the **objectSid** attribute.
   2. Navigate back to the **Summary** tab.
4. In the **Summary** tab, click **Attribute Sources & User Lookup**.
   1. In the **Attribute Source & User Lookup** tab, click **Add Attribute Source**.
      1. In the **Data Store** tab, set the following:
         * *ATTRIBUTE SOURCE ID*: **ActiveDirectory** (or another descriptive name)
         * *ATTRIBUTE SOURCE DESCRIPTION*: **Active Directory** (or another descriptive name)
         * *ACTIVE DATA STORE*: **{Your Active Directory Datastore}**
         * Click **Next**.
      2. In the **LDAP Directory Search** tab, set the following:
         * *BASE DN*: **{Your Active Directory Search Base DN}**
         * *Attributes to return from search*: **objectSid**
         * Click **Next**.
      3. In the **LDAP Binary Attribute Encoding Types** tab, select **SID** as the *Attribute Encoding Type* for *objectSID*, and click **Next**.
      4. In the **LDAP Filter** tab, set **FILTER** to **sAMAccountName=${username}**, click **Next**.
      5. In the **Summary** tab, click **Done**.
   2. In the **Attribute Source & User Lookup** tab, click **Next**.
   3. In the **Adapter Contract Fulfillment** tab, for **objectSid**:
      * Select **LDAP (Active Directory)** as the *Source*.
      * Select **objectSid** as the *Value*.
      * Click **Next**.
   4. In the **Issuance Criteria** tab, click **Next**.
   5. In the **Summary** tab, click **Done**.
5. In the **Adapter Contract Mapping** tab, click **Save**.

## Modify the primary authentication HTML form

The Twosense browser extension detects the presence of the primary login form by looking for a specific attribute in the HTML form. In order to do this, we need to modify the primary login form.

1. Navigate to **AUTHENTICATION** and select **IdP Adapters**.
2. Click on the IdP adapter of your primary login HTML form.
3. Find the name of the HTML form file by looking for the **Login Template** field in the **Summary** tab. The default value is `html.form.login.template.html`.
4. Find the file on your PingFederate instance under `pingfederate/server/default/conf/template/`.
5. Modify the HTML form to include the following attribute in the `<form>` tag `data-twosense-id="primary-login-form"`. The following is an example of a modified HTML form:

   ```html
   <form method="post" action="$url" autocomplete="off" data-twosense-id="primary-login-form">
   ```

## Create HTTP Header Authentication Selector

This selector will be used in the authentication policy to determine if the Twosense browser extension is active during the authentication flow.

1. Navigate to **AUTHENTICATION** and select **Selectors**.
2. Click **Create New Instance**.
3. In the **Type** tab, set the following:
   * *Instance Name*: **Twosense HTTP Header Selector**
   * *Instance ID*: **TwosenseHttpHeaderSelector**
   * *Type*: **HTTP Header Authentication Selector**
   * Click **Next**.
4. In the **Authentication Selector** tab, click **Add a new row to 'Results'**.
   * Set **Match Expression** to **`*`**, click **Update**.
   * Set **Header Name** to **X-Twosense-Extension**.
   * Uncheck **Case-Sensitive Matching**.
   * Click **Next**.
5. In the **Summary** tab, click **Save**.

## Create Authentication Policy

You can create a new authentication policy, or modify an existing one. These instructions will assume you are creating a new policy.

1. Navigate to **AUTHENTICATION** and select **Policies**.
2. Click **Add Policy**.
3. Set **Name** to **Twosense MFA Policy** or another descriptive name.
4. Under **Policy**, select any SP connection Selector you wish to use.
5. Under **NO**, click **Continue**.
6. Under **YES**, select your ***primary login HTML form IdP adapter***.
   1. Under **FAIL**, select **DONE**.
   2. Under **SUCCESS**, select **Twosense HTTP Header Selector**.
      1. Under **NO**, select your ***manual MFA IdP adapter*** (e.g., Duo).
      2. Under **YES**, select your ***Twosense MFA Form***.
      3. Click **Options**, and in the **Incoming User ID** form:
         * Set **Attribute** to **objectSid**.
         * Check **User ID Authenticated**.
         * Click **Done**.
   3. Under **SUCCESS** for the Twosense and manual MFA IdP adapters, select the appropriate policy contract.
   4. Under **FAIL**, select the action you wish to occur when communication between PingFederate and Twosense fails.
   5. Configure the **Rules** for the **Twosense MFA Form** adapter according to the table in the section below.
7. Click **Done**.
8. In the **Policies** tab, click **Save**.

### Twosense MFA Form Adapter Rules

The Twosense adapter will set the `policy.action` attribute to different values for different outcomes. The following table lists the possible values and their meaning. Use these values to create rules to fit your organization's needs.

| **`policy.action` Value** | **Outcome**                                                                                                          |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `no-agent`                | The Twosense agent was not detected on the client machine.                                                           |
| `twosense-client-error`   | An internal error occurred in the Twosense browser extension.                                                        |
| `challenge`               | The user was not authenticated (i.e., due to a low trust score) and should be presented an additional MFA challenge. |

For example, here's how you can customize your policy with rules based on the outcome:

![](/files/FPlQhIPvnpbL6UPuMMLT)

Then you can use these results to determine the next steps in your policy:

![](/files/fuM3dpyXSAWynUTVOcZY)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.twosense.ai/browser-extension-sdk/browser-extension/ping-integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
