Authenticate a User with Duo Security when used as a Backup Factor

This use case provides a step-by-step example of using the Oracle Identity Cloud Service Authentication API to authenticate a user account with Duo Security even when it is configured as a backup factor.

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.

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:

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

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 the response, the nextOp values indicate what can be sent as the op value in the next request. In this use case example, getBackupFactors is sent in the next step.

Step 3: Get the List of Backup Factors

This step enables you to get the list of backup factors.

Request Example

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

{
    "op": "getBackupFactors",
    "requestState": "{{requestState}}"
}

Response Example

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

{
    "status": "success",
    "ecId": "5MyZ41p0000000000",
    "nextAuthFactors": [
        "EMAIL",
        "BYPASSCODE",
        "SECURITY_QUESTIONS",
        "DUO_SECURITY"
    ],
    "EMAIL": {
        "credentials": [
            "preferred",
            "deviceId"
        ],
        "enrolledDevices": [
            {
                "deviceId": "790ed820aee048a78de17ebe1ebddb19",
                "displayName": "ashXXXXX@oracle.com"
            }
        ]
    },
    "BYPASSCODE": {
        "credentials": [
            "bypassCode"
        ]
    },
    "SECURITY_QUESTIONS": {
        "credentials": [
            "questionId",
            "answer"
        ],
        "questions": [
            {
                "questionId": "FirstCar",
                "text": "What's the model of your first car?"
            }
        ],
        "preferred": true
    },
    "DUO_SECURITY": {
        "enrolledDevices": [
            {
                "deviceId": "3053eed6249a4dd4835c51bf873c5f85",
                "displayName": "jarvis's Duo Security Account"
            }
        ]
    },
    "nextOp": [
        "credSubmit",
        "getBackupFactors"
    ],
    "scenario": "AUTHENTICATION",
    "requestState": "{{requestState}}",
    "trustedDeviceSettings": {
        "trustDurationInDays": 15
    }
}

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 4: Select Duo Security from the List of Backup Factors

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",
    "authFactor": "DUO_SECURITY",
    "credentials": {
        "deviceId": "3053eed6249a4dd4835c51bf873c5f85"
    },
    "requestState": "{{requestState}}"
}

Response Example

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

{
	"status": "success",
	"ecId": "5MyZ41q0000000000",
	"DUO_SECURITY": {
	"credentials": [
		 "duoSecurityResponse"
	],
	"authnDetails": {
		"duoSecurityChallenge": "TX
			 |amFydmlzfERJNThZNFhVMlFXWEVSUDQzVTRKfDE1NjE1NjQ1NDg=
			 |230d8328f53ec537ecd033fbb175fbce65930c3e:APP
			 |amFydmlzfERJNThZNFhVMlFXWEVSUDQzVTRKfDE1NjE1Njc4NDg=
			 |af94d927d3e027141177e8f88baa19f6427502ee",
		   "duoSecurityHost": "api-example.duosecurity.com"
		}
	},
	"nextOp": [
		"credSubmit",
	       "getBackupFactors"
	],
	"scenario": "AUTHENTICATION",
	"requestState": "{{requestState}}",
	"trustedDeviceSettings": {
		"trustDurationInDays": 15
	}
}