Enroll a New User with Duo Security

This use case provides a step-by-step example of using the Oracle Identity Cloud Service Authentication API to enroll a new user and an associated device with Duo Security.

Note:

See the Oracle Identity Cloud Service Authentication API Postman collection for extensive authentication use case examples. Download the collection and the global variables file from the idcs-authn-api-rest-clients folder within GitHub and then import them into Postman.

Note:

These steps assume that MFA is enabled and a sign-on policy is created for MFA. See Configuring Multi-Factor Authentication Settings.

Step 1: Begin the Authentication flow

Obtain the initial requestState to begin the authentication flow.

Request Example

The following example shows the request in cURL format :

curl
-X GET
-H "Content-Type: application/json"
-H "Authorization: Bearer {{access_token_value}}"
https://tenant-base-url/sso/v1/sdk/authenticate?appName={{app_name}}

Note:

The appName is optional. The appName is the name of the App that the client wants to access. If an appName is provided, sign-on policies specific to the App are processed, and the client is challenged for the required factors based on that policy.

Response Example

The following example shows the contents of the response in JSON format:

{
	"status": "success",
	"ecId": "HI^kd1M0000000000",
	"nextOp": [
		"credSubmit"
	],
	"nextAuthFactors": [
		"USERNAME_PASSWORD"
	],
	"USERNAME_PASSWORD": {
		"credentials": [
			"username",
			"password"
		]
	},
	"requestState": "{{requestState}}"
}

In the response, the nextOp value indicates what can be sent as the op value in the next request. In this use case example, credSubmit should be sent in the next step. The requestState contains contextual data needed to process the request.

Step 2: Submit the User's Credentials

Submit the user's credentials as the first factor, which are the user name and password. For this step, the client must include the following attributes:
  • credentials: user name and password

  • requestState: received in the Step 1 response

  • op: tells the server what kind of operation the client wants

Request Example

The following example shows the contents of the POST request in JSON format:

{
	"op": "credSubmit",

	"credentials": {
		"username": "{{username}}",
		"password": "{{password}}"
	},

	"requestState": "{{requestState}}"
}

Response Example

The following example shows the contents of the response in JSON format:

{
    "status": "success",
    "ecId": "4uy3^1k0000000000",
    "nextAuthFactors": [
        "TOTP",
        "SECURITY_QUESTIONS",
        "DUO_SECURITY",
        "SMS",
        "EMAIL",
        "PUSH"
    ],
    "EnrolledAccountRecoveryFactorsDetails": {
        "EMAIL": {
            "credentials": [
                "accountRecoveryFactor"
            ],
            "enrolledDevices": [
                {
                    "displayName": "clarence.saladna@example.com"
                }
            ]
        },
        "enrolledAccRecFactorsList": [
            "EMAIL"
        ]
    },
    "TOTP": {
        "credentials": [
            "offlineTotp"
        ]
    },
    "SMS": {
        "credentials": [
            "phoneNumber",
            "countryCode"
        ]
    },
    "nextOp": [
        "createToken",
        "createSession",
        "enrollment"
    ],
    "mfaSettings": {
        "enrollmentRequired": false
    },
    "scenario": "ENROLLMENT",
    "requestState": "{{requestState}}"
}

In this use case example, enrollment is sent in the next step to initiate enrollment for the user.

Step 3: Initiate Duo Security Enrollment Request

This step initiates Duo Security enrollment. The client must include the following attributes:

  • op: tells the server what kind of operation the client wants
  • authFactor: defines which authentication factor the user wants to enroll in
  • requestState: received in the Step 2 response

Request Example

The following example shows the contents of the POST request in JSON format:

{
    "op": "enrollment",
    "authFactor": "DUO_SECURITY",
    "requestState": "{{requestState}}"
}

Response Example

The following example shows the contents of the request in JSON format:

{
	"status": "success",
	"ecId": "4uy3^1k0000000000",
	"DUO_SECURITY": {
	   "credentials": [
		   "duoSecurityResponse"
		],
	   "authnDetails": {
			"duoSecurityChallenge": "TX
			 |amFydmlzfERJNThZNFhVMlFXWEVSUDQzVTRKfDE1NjE1NjMwNTM=
			 |5853cc561ded98c72426b633a1b1e719401e2345:APP
			 |amFydmlzfERJNThZNFhVMlFXWEVSUDQzVTRKfDE1NjE1NjYzNTM=
			 |37f594101a380ff3902e0a2cb545346ed196bbca",
			"duoSecurityHost": "api-example.duosecurity.com"
		}
	},
	"nextOp": [
		 "credSubmit",
		 "createToken",
		 "createSession",
		 "enrollment"
	],
	"mfaSettings": {
		 "enrollmentRequired": false
	},
	"scenario": "ENROLLMENT",
	"requestState": "{{requestState}}"
}

In the response, the nextOp values indicate what can be sent as the op value in the next request. In this use case example, credSubmit is sent in the next step.

Step 4: Initiate Duo Security Authentication

Oracle Identity Cloud Service uses Duo's Web SDK to integrate with Duo Security. Duo offers a JavaScript library that interacts with iFrame that is used for secondary authentication.

After primary authentication, you must pass the authentication details like duoSecurityHost and duoSecurityChallenge that you received from Oracle Identity Cloud Service to iFrame. You can use the following example to initiate the Duo security authentication and load iFrame to make a connection with the Duo Security Server.

function duo(msg, duoSecurityCallback) {
    Duo.init({iframe: "duo_iframe",
            host: msg.DUO_SECURITY.authnDetails.duoSecurityHost,
            sig_request: msg.DUO_SECURITY.authnDetails.duoSecurityChallenge,
            submit_callback: duoSecurityCallback,
            post_argument: "resp"
    });
}

After completing the Duo authentication process, Duo calls the duoSecurityCallback method to get a Duo response.

var duoSecurityCallback = function(details, credentials) {
       var credentials = {};
       credentials.duoSecurityResponse = details.firstElementChild.value;
       operation = "credSubmit";
       initiateAuth(credentials); 
}

Then upon receiving the response for Duo Security, you must pass the response to Oracle Identity Cloud Service to complete the authentication.

Step 5: Submit Factor Credentials

This step submits the factor credentials in the requestState that were received in the Step 3 response. Note that the request payload doesn't contain the authFactor attribute because the requestState contains it. The client must include the following attributes:
  • op: tells the server what kind of operation the client wants
  • requestState: received in the Step 3 response

Request Example

The following example shows the contents of the POST request in JSON format to submit the factor credentials:

{  
   "op":"credSubmit",
   "credentials": {  
       "duoSecurityResponse": "AUTH
		|amFydmlzfERJNThZNFhVMlFXWEVSUDQzVTRKfDE1NjE1NjM5NjA=
		|f2d0df2a189219a8e85db190ac66fab33be996c3:APP
		|amFydmlzfERJNThZNFhVMlFXWEVSUDQzVTRKfDE1NjE1Njc0NTU=
		|a3b7c901e845ebd80451ab670473e983707a8459"
   },
   "requestState":"{{requestState}}"
}

Response Example

The following example shows the contents of the response in JSON format:

{
    "status": "success",
    "ecId": "4uy3^1k0000000000",
    "displayName": "{{username}}'s Duo Security Account",
    "nextOp": [
        "createToken",
        "createSession",
        "enrollment"
    ],
    "scenario": "ENROLLMENT",
    "requestState": "{{requestState}}"
}

The nextOp values indicate what can be sent as the op value in the next request. In this use case example, createToken is sent in the next step.

Step 6: Create the Authentication Token

This step indicates that the client is done and needs a session created. The server validates that no other factor evaluation (depending on what is defined for the policy) is needed and responds with the token or denies access. The client must include the following attributes:
  • op: tells the server what kind of operation the client wants
  • requestState: received in the Step 5 response

Request Example

The following example shows the contents of the POST request in JSON format:

{  
   "op":"createToken",
   "requestState":"{{requestState}}"
}

Response Example

The following example shows the contents of the response in JSON format:

{
    "authnToken": "{{authnToken}}",
    "status": "success"
}