Multi Factor Authentication using Duo Security

Introduction

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.

Setup

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.

Demo

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.

 

Algorithm

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

func process[] {

    On LOGIN_START,

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

            set-next-auth-state[poll-step]

    On STATE_AUTH,

               poll-Duo-REST-API[transactionId];

               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