Multi Factor Authentication using Duo Security


Duo Security provides an array of security products including Duo Mobile which is a stronger method of authentication using a registered device per user. More details can be found here Duo Mobile.

OpenAM is able to invoke the Duo Security API with the “push” factor that uses a push notification to the Duo Mobile app installed on your device for one-tap authentication. Please note that the demo presented here is purely for instructional purposes.


The user and device are first registered with the Duo Security application platform. This is done by the designated administrator. Multiple integrations can be created per organization allowing categorization of user communities by device, geo location or other factors.

Configuration in Duo


You can setup certain users with special privileges such as “bypass”, etc.

The user-id in Duo Security must match the user-id in OpenAM’s user repository for the authentication to succeed.

Configuration in OpenAM

Chain the DataStore module with the custom Duo module.


The user simply has to enter username and password to OpenAM. After verification of username and password, OpenAM starts the Duo custom authentication module.

After hitting submit, the following placeholder screen is shown. This is automatically refreshed until the user accepts or rejects the logon attempt from their device.

The custom authentication module invokes the Duo REST API with factor=push, and username. The request is signed with the integration key and secret key. A transaction id is returned that is saved for polling the request in the next step. The user gets a push notification on their Duo Mobile app.

After opening the Duo Mobile app the user is presented with an accept/deny screen.

Meanwhile, OpenAM polls the Duo REST API using the transaction id to check if the user accepted the push-notification. If so, they are immediately logged into OpenAM.

The user may decline the logon attempt.

The user may indicate whether it was a mistake or seems fraudulent.


If declined, authentication to OpenAM is denied immediately.



Simplified pseudo-code for a custom authentication module is presented here.

func process[] {






               if “waiting”, set-next-auth-state[poll-step]

               if “allow”, set-next-auth-state[LOGIN_SUCCEED]

               if “deny”, throw Exception


func get-transactionId-from-Duo-REST-API[] {

    invoke-HTTP-POST on /auth/v2/auth


func poll-Duo-REST-API[] {

    invoke-HTTP-GET on /auth/v2/auth_status


Source Code

OpenAM Duo Security module on Github

Geo-Fencing using Pitney Bowes ReverseGeocode API


Latitude. Longitude. They’re a way of reaching consumers based not just on transactional data, but also where they are at any given moment. It is possible to protect data by reaching consumers on the go. Precision Reverse Geocoding, only from Pitney Bowes Software, uses a smartphone’s GPS signal to pinpoint a consumer’s location. That location can then be used to determine proximity to secured data zones and even cross-referenced with nearby mobile users within an individual’s social network. Details can be found at Pitney Bowes Geocoding.

While location coordinates can be used for increasing sales and relevance in the Retail and Fast Moving Consumer Goods industries, there are authentication and authorization use cases for the security market as a whole that could use geo-fencing. This technology could enable an organization to protect data from unauthorized access by ‘enveloping’ it with an authorization protocol based on geo-location. Devices that are able to transmit geolocation to OpenAM using either the built-in GPS, or by other means, may then be checked for authorized access based on the current user location before access to data is permitted. This can be accomplished simply by using a scripted authentication connector in OpenAM and the Pitney Bowes ReverseGeocodeUSLocation API.


For the purpose of this demo, we will use a scripted authentication module in OpenAM with the client side script supplying the latitude and longitude, as shown here:

When the user hits the OK button, the coordinates are submitted to the server side script, which then makes an authenticated REST call to the ReverseGeocodeUSLocation Pitney Bowes API.

If the user is within the approved zone for this particular request for access, then she is granted permission to proceed, otherwise an authentication denied error is shown. In our case here, if the demo device is moved more than 15 feet away, our position coordinates change to the address of my neighbor, as shown here:

Since these one-shot coordinates map to a different street address than the one permitted, for this demo anyway, authentication is immediately denied:

If I stay within the approved zone when logging on to OpenAM from my device, the access attempt is approved.

Client Side Script

The client side script uses the Mozilla Geolocation API to retrieve the coordinates which are passed on to the server side script in the clientScriptOutputData JSON object. The implementation of the Geolocation API is based on the W3C Geolocation API Specification. The Geolocation API defines a high-level interface to location information associated only with the device hosting the implementation, such as latitude and longitude. The API itself is agnostic of the underlying location information sources. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. No guarantee is given that the API returns the device’s actual location. The API is designed to enable both “one-shot” position requests and repeated position updates, as well as the ability to explicitly query the cached positions. Location information is represented by latitude and longitude coordinates. For purposes of this demo, no special coding provisions were made to reject potentially cached position coordinates.

Server Side Script

The server side script extracts the coordinates, creates an HTTP Basic authorization header and calls the ReverseGeocodeUSLocation API. The API could easily be modified to permit HTTP Token or other forms of authorization. Note that in OpenAM 12 it is not currently possible to pass an HTTP authorization header and therefore a custom build was used to perform this integration. This facility will be available in OpenAM 13. The API returns the complete Census output fields containing U.S. Census information about the coordinates, including the precise street address. This street address is extracted from the returned message XML body, and checked with a known value. The demo keeps it simple, obviously. Much more could be accomplished with the data returned from the Pitney Bowes API. One could, for instance, during a “cut over” period, map the coordinates to create a heat-map, or user’s preferred area of usage. This zone could then be used to enforce any departures by denying access to requests for sensitive data outside it. Another use case could be co-relating the user’s one-shot position coordinates with nearby sensors and tags, to determine which building floor or room the user is currently requesting access to the data from, and taking policy actions based on that information.


The API defined in the W3C specification is used to retrieve the geographic location of a hosting device. In almost all cases, this information also discloses the location of the user of the device, thereby potentially compromising the user’s privacy. OpenAM’s use of Mozilla’s implementation of this specification provides a mechanism that protects the user’s privacy by ensuring that no location information is made available through this API without the user’s express permission. In this demo, by attempting a login into OpenAM, with implied access to secured and sensitized data, the user implicitly gives the permission for the location coordinates to be evaluated (shared with Pitney Bowes), however, no information identifying the user is sent over the wire.

Configuring OpenAM IDP Proxy with ADFS and Salesforce


This post will describe how OpenAM can be configured as a hosted SAML Identity Provider Proxy with Salesforce acting as Service Provider, and Active Directory Federation Services 2.0 as the Identity Provider. Note that this use case uses Salesforce as the Service Provider. Note that to a Service Provider, an IdP Proxy looks like an ordinary IdP. Likewise, to an Identity Provider, an IdP Proxy looks like an SP. Thus an IdP Proxy has the combined capability of being both an IdP and SP.

The following table is lifted from Spaces. Like a Web (HTTP) Proxy, an IdP Proxy delivers increased efficiency, security, and flexibility.

Web Proxy IdP Proxy
Efficiency ..cache web pages ..cache attributes
Security ..controlled access to web pages ..controlled access to federation IdPs
Flexibility ..HTTP request/response filtering ..SAML request/response filtering

Presented here is the IdP Proxy flow:

  1. A browser client requests a web resource protected by a SAML SP (Salesforce). If a security context for the principal already exists at Salesforce, skip to step 14.
  2. The client is redirected to the IdP component of the IdP Proxy (OpenAM-IdP0), which is protected by the SP component of the IdP Proxy (OpenAM-SP1).
  3. The client makes a SAML AuthnRequest to the SSO service at OpenAM-IdP0. If a security context for the principal already exists at OpenAM-IdP0, skip to step 10.
  4. The AuthnRequest is cached and the client is redirected to the terminal IdP (ADFS). ADFS presents a BA prompt for authentication by default.
  5. The client makes a SAML AuthnRequest to the SSO service at ADFS. If a security context for the principal does not exist, ADFS identifies the principal.
  6. ADFS updates its security context for this principal, issues one or more assertions, and returns a response to the client.
  7. The client submits the response to the assertion consumer service at OpenAM-SP1. The assertion consumer service validates the assertions in the response.
  8. OpenAM-SP1 updates its security context for this principal and redirects the client to OpenAM-IdP0.
  9. The client makes a SAML AuthnRequest to OpenAM-IdP0, the same AuthnRequest made at step 3.
  10. OpenAM-IdP0 updates its security context for this principal, issues a single assertion, and returns a response to the client. The response may also contain the assertions issued by ADFS at step 6.
  11. The client submits the response to the assertion consumer service at Salesforce. The assertion consumer service validates the assertions in the response.
  12. Salesforce updates its security context for this principal and redirects the client to the resource.
  13. The client requests the resource, the same request issued at step 1.
  14. The resource makes an access control decision based on the security context for this principal and returns the Salesforce landing page to the client.


For starters, please refer to Victor’s excellent post about preparing the metadata files for a similar scenario at SAMLv2 IDP Proxy Part 1.

Follow steps 1-4 in that post to prepare your metadata.

Federation Entities in OpenAM

In this section we will survey the entities you have imported in OpenAM so far:

Circle of Trust


Remote Service Provider: Salesforce

Your settings should be very similar to those presented here:

Signing and encryption can be turned off, if not needed.

This screen shows a critical settings related to the IDP Proxy. Ensure your ADFS 2.0 Entity ID is correctly defined in the list.

Remote Identity Provider: ADFS 2.0

Hosted IDP Proxy

IDP Section

Set “test” as the signer certificate in the IDP section of the Hosted IDP/SP proxy entity.

IDP Section continued..


SP Section

The first page..

Assertion processing screen..

The mapping shown below is critical. Here we map the ADFS credential to an internal (anonymous) user, in our case it is “demo”. It could be “anonymous” if such a user is present in your user repository.

Since ADFS does not support Scoping elements, also necessary to achieve this integration is a custom Service Provider adapter that removes the Scoping element from SAML AuthRequest sent to ADFS.

SP Section Continued..

Add the Entity ID for Salesforce here:


Preliminary Steps: Configure OpenAM

1. Import certificates into OpenAM keystore and Java keystore:

/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias sfdc -file SelfSignedCert_09Mar2014_053347.crt -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias adfs -file adfscert.cer -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -exportcert -alias adfs -file adfscert.crt -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -exportcert -alias sfdc -file sfdc.crt -keystore keystore.jks
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias adfs -file ccgadfs.crt -trustcacerts -keystore /usr/java/jdk1.7.0_45/jre/lib/security/cacerts
/usr/java/jdk1.7.0_45/bin/keytool -importcert -alias sfdc -file sfdc.crt -trustcacerts -keystore /usr/java/jdk1.7.0_45/jre/lib/security/cacerts

2. In OpenAM, after importing the metadata files, add the Federation Authentication Module under /local realm

Step 5: Creating the Single Sign On settings in Salesforce

In Salesforce, under Security Controls -> Single Sign On Settings, create a new “SAML Single Sign-On Setting”, and fill in the Identity Provider Login URL, and Logout URLs from the metadata file “” in Step 4.a.

Step 6: Importing the Service Provider descriptor from the IdP Proxy into ADFS 2.0

On the Windows server, start up AD FS 2.0 Management utility, and create a new relying part trust, by cliking on “Add Relying Party Trust”.

Select “Import data about the relying party from a file”, and use the “” you created in Step 4.c. Call it “Salesforce via OpenAM IDP Proxy” and finish.

Select the newly created relying party and ensure the settings match the screenshots presented here.

For example, change the default SAML ACE from Artifact to POST.

Also, change the secure hash algorithm to SHA-1 as shown here.

Click on “Edit Claim Rules” and follow instructions given in OpenAM and ADFS2 configuration to create the first rule.

Create a custom claim rule using the following script:

c:[Type == ""] => issue(Type = "", Issuer = c.Issuer, OriginalIssuer = c.OriginalIssuer, Value = c.Value, ValueType = c.ValueType, Properties[""] = "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified", Properties[""] = "<entity-id of ADFS 2.0>", Properties[""] = "<entity-id of your IDP proxy>");

You should see two rules now:

Click ok to finish editing claim rules.

Optional ADFS 2.0 configuration

You can configure ADFS to not encrypt or sign SAML responses. Follow these steps if necessary:

  1. Use Windows Power Shell to check for installed ADFS snap-in: Get-PSSnapin -Registered
  2. You should be able to see: Microsoft.Adfs.PowerShell 1.0 “This powershell snap-in contains cmdlets used to manage Microsoft Identity Server resources”
  3. Now proceed to add it : Add-PSSnapin Microsoft.Adfs.Powershell
  4. Configure ADFS to not encrypt SAML response: Set -ADFSRelyingPartyTrust -TargetName “Salesforce via OpenAM IDP Proxy” -EncryptClaims $False
  5. **If you get an erroneous SAML StatusCode “Responder” error in OpenAM during testing, run these commands to turn off certificate revocation checks in ADFS:
    1. Set-ADFSRelyingPartyTrust -TargetName “Salesforce via OpenAM IDP Proxy” -EncryptionCertificateRevocationCheck ‘None’
    2. Set-ADFSRelyingPartyTrust -TargetName “Salesforce via OpenAM IDP Proxy” -SigningCertificateRevocationCheck ‘None’


Navigate to your Salesforce SSO URL, you will immediately be taken to the ADFS basic authentication prompt:


Enter your ADFS domain credentials here and hit Log In. If all is well, you should be taken to your Salesforce landing page.

OpenAM 2FA using the TeleSign PhoneID Score API


TeleSign PhoneID Score combines predictive data from multiple sources, including telecom data, traffic patterns, and reported fraud to assess the risk level of a phone number. The product provides a reputation score, ranging from 0 to 1000, a risk level, and a recommendation based on a user’s phone number. PhoneID Score provides a real-time score, risk assessment, and recommendation. The scoring algorithm is dynamically updated to match ever-changing fraud trends. In fact, whenever a user’s activities change so does the score. More information can be found at TeleSign .

TeleSign Verify SMS API can be used to authenticate a known user, verify a transaction, or block fraudsters from opening thousands of accounts on your site. TeleSign Verify SMS verifies users in real time by sending a one-time verification code via SMS to their mobile phone. TeleSign delivers SMS to more than 200 countries. More info can be found here.


A custom authentication module receives the user’s telephone number, and uses TeleSign PhoneID Score API to evaluate the risk level of the phone number. If the phone number is of acceptable risk (low or moderate), then the authentication module uses the TeleSign Verify SMS API to send a verification code to the phone number entered.

The API returns a risk level for the phone number. If the risk level is “allow”, the module will send a random verify code via the TeleSign Verify SMS API, and upon user entry, use the TeleSign Verify SMS API to verify the code.

If the risk level from Score API is “deny”, OpenAM will show a denied screen to the user. A deny response looks like this:

{"reference_id":"####","sub_resource":"score","errors":[],"status":{"updated_on":"2015-03-10T22:48:59.139040Z","code":300,"description":"Transaction successfully completed"},"numbering":{"original":{"phone_number":"####","complete_phone_number":"####","country_code":"92"},"cleansing":{"sms":{"phone_number":"####","country_code":"92","min_length":9,"max_length":12,"cleansed_code":105},"call":{"phone_number":"####","country_code":"92","min_length":9,"max_length":12,"cleansed_code":105}}},"risk":{"level":"high","score":959,"recommendation":"block"}}

If the user entered an incorrect code, the TeleSign Verify SMS API will indicate as such, and OpenAM will reject the login attempt.

If the verify code validates correctly, then the user simply has to enter their username to login to AM.

An low risk response from the TeleSign PhoneID Score API looks like this:

{"reference_id":"####","sub_resource":"score","errors":[],"status":{"updated_on":"2015-03-10T22:52:17.603141Z","code":300,"description":"Transaction successfully completed"},"numbering":{"original":{"phone_number":"####","complete_phone_number":"####","country_code":"1"},"cleansing":{"sms":{"phone_number":"####","country_code":"1","min_length":10,"max_length":10,"cleansed_code":100},"call":{"phone_number":"####","country_code":"1","min_length":10,"max_length":10,"cleansed_code":100}}},"risk":{"level":"low","score":1,"recommendation":"allow"}}

Note that TeleSign uses a global phone directory, so if you do not prefix your country code, it will take the first digit(s) from the phone from the left and use that to identify the country.

Source Code



This article was first published on the OpenAM Wiki Confluence site: OpenAM and TeleSign Integration