Skip navigation
Documentation

Duo Web v4 SDK - Duo Universal Prompt Public Preview

Last Updated: November 12th, 2020

Add Duo's strong two-factor authentication to your web application, complete with inline self-service enrollment and Duo Prompt.

Web SDK v4 supporting the Duo Universal Prompt is in Public Preview. Contact duo-frameless-integrations-beta@cisco.com with feedback.

Overview

Implementing Duo two-factor authentication into your site involves splitting your login handler into two parts. You should be familiar with your web application's programming language and authentication process. Client libraries are available for Python and Java. Please contact Duo Support if you're interested in SDK support for other languages.

To use a different language or to create your Duo integration without using one of our SDKs, see the OIDC Auth API.

For example, a typical single factor login process looks something like this:

Duo Web Flow Before

After adding Duo authentication it will look more like this:

Duo Web Flow After

Universal Prompt

Duo's next-generation authentication experience, the Universal Prompt, is coming to web-based applications that display the current Duo Prompt in browsers. Migration of Web SDK v2 applications to Web SDK v4 is a prerequisite for enabling the future Universal Prompt experience.

Migration to Universal Prompt for your Duo Web application will be a two-step process:

  • Update the application to support the Universal Prompt by using this Duo Web v4 SDK.
  • Enable the Universal Prompt experience for users of the Duo Web application (when the Universal Prompt becomes available).

If you're creating a Duo Web application for the first time, building it with the Duo Web v4 SDK ensures it will support the Universal Prompt in the future.

The "Universal Prompt" section on the details page of your Duo Web application indicates availability of the update.

Universal Prompt Info

Once a a user authenticates to that application via the Duo v4 SDK, the "Universal Prompt" section of the Duo Web application page reflects this status. When the Universal Prompt becomes available, you'll return here to activate it for users of this application.

Duo Web Universal Prompt Info

Click the See Update Progress link to view the Universal Prompt Update Progress report. This report shows the update availability and migration progress for all your Duo applications that will have Universal Prompt support.

Watch the Duo Blog for future updates about the Duo Universal Prompt.

Upgrading from WebSDK 2

See the Universal Prompt Update Guide for an overview of the new Universal Prompt and its advantages over the previous WebSDK.

The WebSDK 4 Universal Prompt Web SDK is a brand new experience with a substantially different integration flow from the previous WebSDK 2.

WebSDK 4 has some key technical differences from WebSDK 2:

  • No longer displays the Duo Prompt in an iFrame on your website. The prompt is now hosted on Duo’s servers and displayed via HTML redirects.
  • No longer requires you to generate and use an akey value.
  • Provides a health check to ensure that Duo’s servers are fully up and reachable from the client before attempting the Duo authentication.
  • After you complete your first authentication using WebSDK 4, the corresponding "Web SDK" application in the Duo Admin Panel updates to reflect new terminology and functionality. WebSDK 2 clients continue to function with this Duo application.
  • Requires a client id and client secret instead of an ikey and skey (note that these are the same values, relabeled).

If you already have an existing Web SDK application, you do not need to create a new one to migrate it to Web SDK 4. You may reuse that existing integration.

Note: After upgrading your Application to use WebSDK 4, the Duo Prompt will have identical appearance and functionality as the WebSDK 2 prompt. Updating to the new Universal Prompt is a separate step, outlined at /universal-prompt-update-guide

First Steps

Before starting:

  1. Sign up for a Duo account.

  2. Log in to the Duo Admin Panel and navigate to Applications.

  3. Click Protect an Application and locate the entry for Web SDK in the applications list. Click Protect to the far-right to configure the application and get your integration key, secret key, and API hostname. You'll need this information to complete your setup. See Protecting Applications for more information about protecting applications in Duo and additional application options.

    Once you authenticate to this Duo application using Web SDK 4 the "Integration key" and "Secret key" labels update to "Client ID" and "Client secret" respectively.

  4. Use NTP to ensure that your server's time is correct.

Connectivity Requirements

This application communicates with Duo's service on TCP port 443. Firewall configurations that restrict outbound access to Duo's service with rules using destination IP addresses or IP address ranges aren't recommended, since these may change over time to maintain our service's high availability. If your organization requires IP-based rules, please review this Duo KB article.

Add the duo-universal Dependency to your Project

Client libraries are currently offered for Python and Java. To integrate with another language, please see the Duo OIDC-based API documentation.

Python

Issue the following command:

pip install duo_universal

Refer to the Duo Universal Prompt Python sample project for a complete example of how to use the SDK.

Java

View the Duo Universal Prompt Java sample project for a complete example of how to use the SDK.

Maven

Add the following to the <dependencies> section of your pom.xml:

<dependency>
  <groupId>com.duosecurity</groupId>
  <artifactId>duo-universal-sdk</artifactId>
  <version>1.0.3</version>
</dependency>

Gradle

Add the following to the dependencies section of your build.gradle:

implementation group: "com.duosecurity", name: "duo-universal-sdk", version: "1.0.3"

Manual

Find the latest jar on the duo_universal_java Github releases page.

Detailed SDK Workflow

Create a Client() object

After you perform primary authentication (e.g. look up a user's username and password in your database), you should create a Client() object which initializes the secondary authentication process.

Client() takes your Duo Web application's Client ID (or Integration key) as client_id, Client secret (or Secret key) as client_secret, and API hostname as api_host information from the Duo Admin Panel, as well as a redirect uri which Duo will use to redirect back to your application after authentication.

What should I use as the redirect URI?

The redirect URI will be a separate endpoint on your service that listens for the Duo Prompt redirection callback. E.g. if your login form is at https://example.com:8080/login, then your redirect uri could be https://example.com:8080/duo-callback. This URI does not need to be publicly accessible by Duo, it will only be accessed from the end-user’s web browser.

Python Example

import duo_universal
duo_client = duo_universal.Client(client_id, client_secret, api_host, redirect_uri)
Safeguard your client secret (secret key)!

The security of your Duo application is tied to the security of your client secret (secret key). Treat these pieces of data like a password. They should be stored in a secure manner with limited access, whether that is in a database, a file on disk, or another storage mechanism. Always transfer them via secure channels, and do not send them over unencrypted email, enter them into chat channels, or include them in other communications with Duo.

Call health_check()

A call to health_check() determines if Duo’s servers are accessible and available to accept the 2FA request. If Duo’s servers are inaccessible for any reason (e.g. networking issues, services outage), this method raises an error, and your application can decide how to proceed (i.e. to “Fail Open” and allow the login without completing Duo authentication, or to “Fail Closed” and prohibit the login completely).

Python Example

try:
  duo_client.healthcheck()
except DuoException:
  # Either allow login without 2FA, or abort the login process

Call generate_state()

generate_state() generates a session identifier. This identifier will be passed to Duo, and should also be stored locally in your code use later to validate Duo's responses. The validation will occur in a different endpoint / web request, so you should store the state in your web framework’s session.

Python Example

state = duo_client.generate_state()
flask.session[‘state’] = state

Call create_auth_url()

create_auth_url() takes the user’s username and the previously generated state and returns a URL to a Duo-hosted endpoint.

Python Example

prompt_uri = duo_client.create_auth_url(username, state)

Redirect the Client

Redirect the client web browser to the previously created URI. This is where the end-user is shown the Duo Prompt to complete their authentication. The redirect code is specific to your web framework.

Python Example (Using Flask)

return flask.redirect(prompt_uri)

Wait for the Redirect from Duo back to your Redirect URI

After Duo successfully verifies the user — authentication approval via phone call, SMS passcode, Duo Push, etc. or permitted access with bypass of interactive authentication after Duo policy evaluation — their browser is then redirected to the redirect_uri specified earlier in the Client() object. This URI should be an endpoint in your service which completes the remainder of the end-user’s login.

This request includes two GET parameters: state and code.

Python Example (Using Flask)

@app.route("/duo-callback")
def duo_callback():
   state = request.args.get('state')
   code = request.args.get('code')

Validate the state Parameter

The state parameter value received from the redirect should be validated against the previously saved state value. If they don't match, this indicates a security issue and the login attempt should be aborted.

Python Example

if state != flask.session['state']:
# Abort login attempt

Call exchange_authorization_code_for_2fa_result()

exchange_authorization_code_for_2fa_result() takes the code parameter from the previous step, as well as the username. This method calls Duo’s service to have your server validate that the user successfully authenticated with Duo.

This method raises a DuoException if the user fails Duo authentication for any reason. If it does not raise an error, then the user has successfully completed Duo authentication. The returned token object contains metadata about the authentication.

Python Example

try:
  decoded_token =
duo_client.exchange_authorization_code_for_2fa_result(code, username)
except DuoException as e:
  # Handle authentication failure.
# User successfully passed Duo authentication.

Troubleshooting

Need some help? Take a look at our WebSDK Knowledge Base articles or Community discussions. For further assistance, contact Support.