RapidIdentity Authentication API Guides
There are three main API calls involved in the Modular Authentication API.
Endpoint | Description |
---|---|
GET /idp/ws/rest/authn/krb | Attempt to initialize the process with Kerberos SSO. See Kerberos. |
GET /idp/ws/rest/authn | Initialize the authentication process and receive the initial authentication step. See Initialization. |
POST /idp/ws/rest/authn | Submit an authentication step and receive the next step. |
Each response from the server and associated request from the client is a JSON object which has at the very minimum a type and id field.
In a response from the server, the type field indicates the next authentication method required to proceed.
The id field is an opaque value which has no meaning in-and-of-itself. All requests from the client should contain the same id value which was previously included in the response from the server.
During the authentication process, the server currently maintains session data using the Java HttpSession mechanism and this is bound to a particular client using a HTTP Cookie. This implies that the client must support cookies in order to use RapidFederation Modular Authentication.
The Authentication API Consumer allows access to all of the API endpoints listed in the table below.
Authentication Method API | Details |
---|---|
Username | This API should be used to identify a user by "username" and receive the idautoID of that user. |
QR Code | This API should be used to identify a user by QR code and receive the idautoID of that user. |
OTP | This API should be used to authenticate a user by OTP code. |
Pictograph | This API should be used to authenticate a user by Pictograph code. Pictograph authentication requires the client to first request a "challenge set" from the server. The response contains various inner and outer arrays. The inner arrays include objects that represent a set of images to be used to challenge the user, along with the valid choice for the user. The outer array contains "n" inner arrays where "n" is also the number of choices the user must answer correctly. ImportantWhen the client requests the Pictograph challenge for a particular user, the response will include a "cookie" string. This value must be included in the next request that includes the list of selected image IDs to successfully complete a Pictograph authentication. |
PingMe | This API should be used to authenticate a user by PingMe code. PingMe authentication is performed by first requesting the server send a PingMe notification to all of the target user's registered devices and then polling for the response. |
Proximity Card | This API should be used to identify a user by proximity card (contactless smart card) and receive the idautoID of that user. |
Exchange | The Exchange API may be used by the client to exchange claims previously received on behalf of an authenticating user. |
Available Authentication Methods
Failure
If an un-recoverable failure occurs during the authentication process the server will send a response with the type property value fail and generally some kind of error object that in some way explains what went wrong. The only reasonable thing for the UI to do in this situation is to display the error message and allow the user to start over.
HTTP/1.1 200 OK Content-Type: application/json { "type": "fail", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "error": { "type": "simple", "message": "Unable to complete the authentication process. Please try again later" } }
Completion
When the authentication process has completed successfully, the server will send a response with the type property value complete.
HTTP/1.1 200 OK Content-Type: application/json { "type": "complete", "id": "931c4a40-2dc9-11e6-937b-005056c00008" }
In order to finalize the SAML authentication process, the browser should then issue a POST to /idp/authn/idauto with a parameter complete and a value of 1. This will indicate to the IdP's SAML engine that the user has authenticated successfully and the user should then be forwarded on to their destination application with a valid SAML Assertion.
FIDO Authentication
Here is an example response from the server indicating that FIDO Authentication is required as the next step:
Note
Displayed values have been truncated here for formatting purposes, but the strings listed here should represent actual, usable values when generated in a production environment.
HTTP/1.1 200 OK Content-Type: application/json { "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "step": { "appId": "https://rapidIdentity.example.com:8443/FIDO/appId", "challenge": "g9WMWOFyFef8x9nNwt4zfZnJhaLHoSyKEprXT_EGPxU", "devices": [ { "name": "FIDO Device - (ID: a28af5qa-f4r2-4271-a926-7d09537f869c)", "deviceId": "a24af5ca-f4f2-4171-a936-7d01567f869c", "keyHandle": "jwCS9L5WAxN4PjZFjIOgv-D9FE0Fze_[...]_CsCSUQtI__[...]" } ], "type": "authenticate", "userId": "8e123420-00e4-11r6-c668-005056r00008", "version": "U2F_V2" }, "type": "fido" }
Note that the value of the type property is fido
and the step.type property is authenticate
.
When responding to the FIDO Authenticate response, a value for the clientData and signatureData properties are required. These values should be generated between the FIDO device and client.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "step": { "clientData": "eyJvcmlnaW4iOiJodHRwczovL2xvY2FsaG9zdDoyNTE0OCIsImNpZF9wdWJrZ[...]", "signatureData": "AQEBAQEiYycLYY0_EHePpkSt22mTwjZJ2HMCIF9IE_gT0jmxaknCyM4cbp[...]", "defer": false, "type": "authenticate" }, "type": "fido" }
Here is an example response from the server indicating that FIDO Registration is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "step": { "appId": "https://rapidIdentity.example.com:8443/FIDO/appId", "challenge": "g9WMWOFyFef8x9nNwt4zfZnJhaLHoSyKEprXT_EGPxU", "passwordRequired": true, "name": "FIDO Device - (ID: a28af5ca-f4f2-4271-a946-7d09567f869c)", "deviceId": "a28af5ca-f4f2-4271-a946-7d09567f869c", "type": "register", "userId": "8e193920-00e4-11e6-a668-005056c00008", "version": "U2F_V2" }, "type": "fido" }
Note that the value of the type property is fido
and the step.type property is register
.
When responding to the FIDO Register response, a value for the clientData and registrationData properties are required. These values should be generated between the FIDO device and client. The password property is only required if the user has yet to enter a password or authenticate using a Pre-Auth authentication type.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "id": "e230e2e0-25re-11s5-8da9-0050b6c32ffc", "step": { "clientData": "eyJvcmlnaW4iOiJodHRwczovL2xvY2FsaG9zdDoyNTE0OCIsImNpZF9wdWJrZXki[...]", "registrationData": "BQQtRU22R6qjdGYw3d1JWg5dxy7W2Y8_YXxbYLyn_NzXV6SNhabfaoSzkDwsoheJ[...]", "password": "p@$$w0rd", "type": "register" }, "type": "fido" }
Initialization
If Kerberos authentication was not successful, then the way to proceed is to issue the following request:
GET /idp/ws/rest/authn HTTP/1.1 Accept: application/json
The response from the server will always be of type username, username+password or policyChoice and will contain other pieces of information needed to construct the initial authentication page:
HTTP/1.1 200 OK Content-Type: application/json { "type": "username+password", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "availableRealms": [ { "id": "internal", "name": "Internal" }, { "id": "11541860-161f-11e6-aec5-005056c00008", "name": "Realm 1" }, { "id": "233d3570-161f-11e6-aec5-005056c00008", "name": "Realm 2" } ], "allowQRCodeScan": false, "allowKerberos": false, "claimAccountLink": { "href": "/arms/claim/", "displayName": "Claim My Account" }, "helpLinks": [ { "href": "/arms/forgotmyusername", "displayName": "Forgot My Username" }, { "href": "/arms/forgotmypassword?redirect_to=/arms", "displayName": "Forgot My Password" } ] }
Let's ignore the type for now, it will be discussed later.
The id property is a value that must be included in the subsequent request
The availableRealms property is an array of authentication realms to which the user may authenticate. This is only included if RapidFederation is currently configured for realms other than the default which has the id value of internal.
The allowQRCodeScan property is a boolean indicating that the user may initiate the authentication process by scanning a QR code
The allowKerberos property is a boolean indicating that the user may initiate the authentication process by attempting Manual Kerberos Authentication.
The claimAccountLink object contains the link location (href) as well as the text to display on the button (displayName) which allows a user to claim their account. This object will only be included in the response if the link should be displayed.
The helpLinks property is an array of objects describing help links and their display names which should be available to the user when they click the "Need help?" button on the login page. If no help links are configured, this property will not be included.
Username/Password
This initial authentication step is required if the type property in the initial response has the value username+password. It indicates that
There are no enabled Authentication Policies defined for RapidFederation OR
All enabled Authentication Policies require Password as the initial authentication method
A valid username and password combination is required to proceed to the next authentication step:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "username+password", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "username": "someuser", "password": "mysecurepassword" }
Additionally, if authenticating against a realm other than internal is desired, the realm property may be included in the request body:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "username+password", "realm": "233d3570-161f-11e6-aec5-005056c00008", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "username": "someuser", "password": "mysecurepassword" }
Here is an example of a response from the server if the username/password combination sent in the request is incorrect:
HTTP/1.1 200 OK Content-Type: application/json { "type": "username+password", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "availableRealms": [ { "id": "internal", "name": "Internal" }, { "id": "11541860-161f-11e6-aec5-005056c00008", "name": "Realm 1" }, { "id": "233d3570-161f-11e6-aec5-005056c00008", "name": "Realm 2" } ], "claimAccountLink": { "href": "/arms/claim/", "displayName": "Claim My Account" }, "helpLinks": [ { "href": "/arms/forgotmyusername", "displayName": "Forgot My Username" }, { "href": "/arms/forgotmypassword?redirect_to=/arms", "displayName": "Forgot My Password" } ], "error": { "type": "simple", "message": "Incorrect Username and/or Password" } }
Notice the error property in the response. It has a type value of simple which means that the associated message should be displayed to the user.
Here is an example of the response from the server if the username & password combination were correct but the user is required to update their password before continuing:
HTTP/1.1 200 OK Content-Type: application/json { "type": "username+password", "id": "cd4f0ab0-2dc7-11e6-937b-005056c00008", "availableRealms": [ { "id": "internal", "name": "Internal" }, { "id": "11541860-161f-11e6-aec5-005056c00008", "name": "Realm 1" }, { "id": "233d3570-161f-11e6-aec5-005056c00008", "name": "Realm 2" } ], "claimAccountLink": { "href": "/arms/claim/", "displayName": "Claim My Account" }, "helpLinks": [ { "href": "/arms/forgotmyusername", "displayName": "Forgot My Username" }, { "href": "/arms/forgotmypassword?redirect_to=/arms", "displayName": "Forgot My Password" } ], "error": { "type": "password-expired", "message": "Your password is expired and must be updated before continuing", "expiredPasswordText": "CLICK HERE to change your password.", "targetUrl": "/arms/expired-password", "username": "8kb+8GQVM2HUGJQtMRxKjNFfUNuboOhcdtBw8VtIlZU=", "password": "78EV3jkq6IYu/8S2rC4M54NQYwTQRPRaUEaFuNdRx6w=" } }
Notice the error property in the response. It has a type value of password-expired which indicates that the user must change their password and the associated message should be displayed to the user to let them know. The expiredPasswordText, targetUrl, username and password property values are used to construct a link which, when clicked, submits a form in a new window which POSTs the obfuscated username and password to the targetUrl.
Username
This initial authentication step is required if the type property in the initial response has the value username. It indicates that
There is at least one enabled Authentication Policies defined for RapidFederation AND
At least one of the enabled Authentication Policies requires an initial authentication method other than Password.
A valid username is required to proceed to the next step:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "username+password", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "username": "someuser" }
Additionally, if authenticating against a realm other than internal is desired, the realm property may be included in the request body:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "username+password", "realm": "233d3570-161f-11e6-aec5-005056c00008", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "username": "someuser" }
If a username which does not successfully map to a valid account is provided in the username request, it will kick off a "Bogus" authentication flow which will always fail.
PolicyChoice
This authentication step allows users to select which authentication policy they want to use to authenticate, and is only present if:
There are multiple authentication policies which are applicable to a user
Authentication Policy Options have been "opted-in" to
Here is an example of the response from the server if either username or username+password has been completed successfully and authentication policy options are enabled:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "policyChoice", "id": "2f875a60-dbfc-11e6-8449-005056c00008", "claimAccountLink": { "href": "/arms/claim/", "displayName": "Claim My Account" }, "helpLinks": [ { "href": "/arms/forgotmyusername", "displayName": "Forgot My Username" }, { "href": "/arms/forgotmypassword?redirect_to=/arms", "displayName": "Forgot My Password" } ], "policies": [ { "id": "5fda6a30-d1ee-11e6-8629-005056c00008", "methods": [ { "type": "password" } ] }, { "id": "4101afb0-d1ee-11e6-8629-005056c00008", "methods": [ { "type": "password" }, { "type": "rapidPortalChallenge" } ] } ] }
Next, the user returns a request with the policy ID that they would like to authenticate with:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "id": "65a22d80-d9c9-11e6-9ed6-005056c00008", "type": "policyChoice", "policyId": "5fda6a30-d1ee-11e6-8629-005056c00008" }
Kerberos
If the API is being invoked from a browser, the first step in the process should be attempting Kerberos SSO. The following request should be issued:
GET /idp/ws/rest/authn/krb HTTP/1.1 Accept: application/json
If Kerberos authentication is successful, the server will return a status of 200 and the JSON data for the next authentication step to perform will be included in the response. In the event that Kerberos is the only authentication method required for the user, the next step will of type compete which indicates that no further authentication steps are required.
If Kerberos authentication is successful it means that the username of the user is known and a username prompt is not required to initiate the RapidFederation authentication process.
If any other status besides 200 is returned, then it means that Kerberos authentication failed and the authentication process should proceed with the Initialization step.
Manual Authentication
An internal engineering ticket was opened to address an issue with automatic Kerberos processing and, as such, we've had to slightly adjust how Kerberos works. Specifically, there is a new option in the Kerberos Configuration which allows an admin to toggle "Automatic Kerberos Processing". From the server's point of view if automatic processing is turned off, this means that all Kerberos requests made at the very beginning of the process will automatically fail, however the response from the normal init call at /idp/ws/rest/authn/ will have a new allowKerberos flag set to true. This indicates to the client that manual Kerberos authentication is enabled and the user should be given the option to do so if they wish. A manual Kerberos request is exactly the same as the automatic one except that a request parameter requested must be present with the value true.
GET /idp/ws/rest/authn/krb?requested=true HTTP/1.1 Accept: application/json
Everything else about the response will be the same as with automatic processing.
As an Authentication Policy Criteria
If Kerberos criteria is enabled for a given policy, it means that only users who have successfully completed Kerberos authentication will be eligible for that policy.
As an Authentication Method
If the Kerberos authentication method is enabled for a given policy, it means that Kerberos authentication is required to have completed successfully or authentication will automatically fail.
Example Javascript
This example demonstrates how to attempt Kerberos authentication against RapidFederation using JQuery
< script > $.ajax({ type: 'GET', url: '/idp/ws/rest/authn/krb', cache: false, async: true, xhrFields: { withCredentials: true } }).done(function(data) { //data should contain a JSON object }).fail(function() { //kerberos failed, go ahead and call /idp/ws/rest/authn to get the first step }); </script>
Password Authentication Method
Here is an example response from the server indicating that password authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "password", "id": "931c4a40-2dc9-11e6-937b-005056c00008" }
Note that the value of the type property is password.
In addition to sending the standard id and type properties with the next request, the only other thing required is a valid password:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "password", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "password": "mysecurepassword" }
If the password provided is correct, then the next authentication step will be returned by the server. If not a password type will be returned with an error property.
Here is an example of a response from the server if the password sent in the request is incorrect:
HTTP/1.1 200 OK Content-Type: application/json { "type": "password", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "error": { "type": "simple", "message": "Incorrect Username and/or Password" } }
Notice the type of the error is simple. This indicates that the associated message should be displayed to the user and they should be prompted again for a valid password.
Here is an example of the response from the server if the password was correct but the user is required to update their password before continuing:
HTTP/1.1 200 OK Content-Type: application/json { "type": "password", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "error": { "type": "password-expired", "expiredPasswordUrl": "https://customer.rapididentity.com/", } }
Notice the type of the error is password-expired. This indicates that the user must change their password. If expiredPasswordUrl
is not included in the response, it indicates that the Expired Password Flow should be executed against the current server URL. If the property is included in the response, the Expired Password Flow should be executed against the server whose URL is provided.
If RapidIdentity detects that a user's password is expired during a login attempt, here are the new APIs to facilitate a successful password change.
Once the user's password is detected as expired, here is the new update password init request:
POST /expiredPassword/init HTTP/1.1 Content-Type: application/json { "userId": "321g4a40-2dd4-11e6-937b-005056c24006", "currentPassword": "mysecurepassword" }
If the request is successful, the server will respond with the following response, containing a token and the password policy associated with the user:
HTTP/1.1 200 OK Content-Type: application/json { "token":"wsJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.bEkmBEgjf7PivEbXkJjg5PYABZ8DooSUO1jAWTBfY4ZfNWvtxjss1l2k_00WV8Kfuc9XQGVWDgbJe6nYZE5kY95SZ144ioDdS0a7aCeMKS2azFI142iBx5P1vNakYRoVhV7dwCYN7oLHXQBe7fqaYHDbUStCrGzm1rOe4jFTfOHrNIve6x4aLdW3N4M7inTdZK7v3t2_FeCbG9g06A09N75jmJ26uwcQXh7eez9nEnBrzeh7JnGA18UJsYHhpaoqftdMV52NDNIw6os7zM9352R3xEzZErK-mD0Cw42G1zr9zk_dfd0z0RyF5pr9yFVYbY9mga6_vVmBOhTsnFzPIA.4XSwi4xokumtM-w7.3sBpe1XM34pG2CkKl9XUvSLd9y2C7A4I3Nz5PNNw1ZLzGecverVYkh5HKpjH9EI-6Qv4rfovzpqh_rt-JbaBNhqU5jZgA0v4HEQJwJaY8oJ7Q8TI3oiLtqvi-r6kmXKDixSj7BbwQ5kQ2o4S9Wx13O60MtzCH7dvFryRxHYvyblvSUpSXoqKGy5Zljf7nWPLFjq2RYRG6vUHkOE1CfYO2BqoEkTILe7Eqg4sD7BiTilz2u90uGIRafxdC0PUThMfNY6zlGH0LsT9YUDmU4O2pWGz5yzHYNXKRAHRUu-Oz3KQI0FVNXdKEiQl6CWeErOxM8Efin67TKZUVx745ddL-BZGqoyaEmktu71mfRMHXX6sDBQwvQdXeZG3VpHdbqvU9ycavjsEJhnEVFBaTrpu5G-nTiX0yZKRMeIKyIr1PsoGRgqNTfL7W1lGCb68n45UNXIr2sq3eGS8arCIAPzYPszPGDkWzXNy4EF8dMY4py9ml29GLm2QTTW4rEL6d2VU-rebf5JstINVg5s-We-ugyEyBVE-03VjpZRMFkA3jMNbm_kK5UTU0bi7BYb2912wA6Mcc0wCPK_3F1pW2Zljgto1isBOk9--iR5MIuVt91rxfUs7Fzv2-wFrni2aaW1dxgIjmb_rnBlM_mH4USFtC2ueNv-Vz-QQBOm37W0I-KSXBuiDl_qUMRBDE0DKDsgyuAJ2a9dmVF9F5Oqw5wvQEtQttbJfh0RhhB8WX42kK5cNIp96da4kSxvLplPpAh33kv2WGLcjMoxnWGEdjo2e2Riz2IxWg3mMOoAoRM3uCIJUi6Z83SdmmfpCcl2uV_1ztgplmiayLpj6Pa68AxkM7wt7tASH9GcVN92zvFWgKco033RE6jRGWPNXtOhVvgQPaEUI0E4te3_CXhGB2WPmKKPIsBiBWDZFA34cVMQbUSUTfM-PwYBPdAf-.pK1LGDsQ0W12JJZLz_sD3x", "passwordPolicy": { "id": "c61e98ee-204b-405f-a271-d351a8ecf784", "name": "Default Password Policy", "description": "[Add a description]", "minLength": 3, "maxLength": 255, "charSets": [ { "id": "charset.lower", "type": "LOWER", "min": 1, "max": 0 }, { "id": "charset.digits", "type": "DIGITS", "min": 1, "max": 0 }, { "id": "charset.symbols", "type": "SYMBOLS", "min": 1, "max": 0 }, { "id": "charset.upper", "type": "UPPER", "min": 1, "max": 0 } ], "requiredCharSets": 0, "allowRandomPassword": false, "matchingAttributesCaseSensitive": false, "matchingAttributesMatchEntire": false, "blackListed": [], "blackListCaseSensitive": false, "blackListMatchEntire": false, "blackListRegexes": [], "defaultForceUserPasswordChange": true } }
The next step will be to test the user's new password against the password policy. An example of that request would be:
POST /expiredPassword/test HTTP/1.1 Content-Type: application/json { "token":"wsJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.bEkmBEgjf7PivEbXkJjg5PYABZ8DooSUO1jAWTBfY4ZfNWvtxjss1l2k_00WV8Kfuc9XQGVWDgbJe6nYZE5kY95SZ144ioDdS0a7aCeMKS2azFI142iBx5P1vNakYRoVhV7dwCYN7oLHXQBe7fqaYHDbUStCrGzm1rOe4jFTfOHrNIve6x4aLdW3N4M7inTdZK7v3t2_FeCbG9g06A09N75jmJ26uwcQXh7eez9nEnBrzeh7JnGA18UJsYHhpaoqftdMV52NDNIw6os7zM9352R3xEzZErK-mD0Cw42G1zr9zk_dfd0z0RyF5pr9yFVYbY9mga6_vVmBOhTsnFzPIA.4XSwi4xokumtM-w7.3sBpe1XM34pG2CkKl9XUvSLd9y2C7A4I3Nz5PNNw1ZLzGecverVYkh5HKpjH9EI-6Qv4rfovzpqh_rt-JbaBNhqU5jZgA0v4HEQJwJaY8oJ7Q8TI3oiLtqvi-r6kmXKDixSj7BbwQ5kQ2o4S9Wx13O60MtzCH7dvFryRxHYvyblvSUpSXoqKGy5Zljf7nWPLFjq2RYRG6vUHkOE1CfYO2BqoEkTILe7Eqg4sD7BiTilz2u90uGIRafxdC0PUThMfNY6zlGH0LsT9YUDmU4O2pWGz5yzHYNXKRAHRUu-Oz3KQI0FVNXdKEiQl6CWeErOxM8Efin67TKZUVx745ddL-BZGqoyaEmktu71mfRMHXX6sDBQwvQdXeZG3VpHdbqvU9ycavjsEJhnEVFBaTrpu5G-nTiX0yZKRMeIKyIr1PsoGRgqNTfL7W1lGCb68n45UNXIr2sq3eGS8arCIAPzYPszPGDkWzXNy4EF8dMY4py9ml29GLm2QTTW4rEL6d2VU-rebf5JstINVg5s-We-ugyEyBVE-03VjpZRMFkA3jMNbm_kK5UTU0bi7BYb2912wA6Mcc0wCPK_3F1pW2Zljgto1isBOk9--iR5MIuVt91rxfUs7Fzv2-wFrni2aaW1dxgIjmb_rnBlM_mH4USFtC2ueNv-Vz-QQBOm37W0I-KSXBuiDl_qUMRBDE0DKDsgyuAJ2a9dmVF9F5Oqw5wvQEtQttbJfh0RhhB8WX42kK5cNIp96da4kSxvLplPpAh33kv2WGLcjMoxnWGEdjo2e2Riz2IxWg3mMOoAoRM3uCIJUi6Z83SdmmfpCcl2uV_1ztgplmiayLpj6Pa68AxkM7wt7tASH9GcVN92zvFWgKco033RE6jRGWPNXtOhVvgQPaEUI0E4te3_CXhGB2WPmKKPIsBiBWDZFA34cVMQbUSUTfM-PwYBPdAf-.pK1LGDsQ0W12JJZLz_sD3x", "newPassword": "mynewsecurepassword" }
If the request is successful, then the server will respond with the following:
HTTP/1.1 200 OK Content-Type: application/json { "result": true }
If an error occurs during the request, there will be a similar response with an added message property that looks like this:
HTTP/1.1 400 Bad Request Content-Type: application/json { "httpStatusCode": 400, "message": "Error message details", }
The final API is the request to update the user's password. The request body is the exact same as the request to test the user's new password; however, the URL is different.
POST /expiredPassword/updatePassword HTTP/1.1 Content-Type: application/json { "token":"wsJjdHkiOiJKV1QiLCJlbmMiOiJBMjU2R0NNIiwiYWxnIjoiUlNBLU9BRVAtMjU2In0.bEkmBEgjf7PivEbXkJjg5PYABZ8DooSUO1jAWTBfY4ZfNWvtxjss1l2k_00WV8Kfuc9XQGVWDgbJe6nYZE5kY95SZ144ioDdS0a7aCeMKS2azFI142iBx5P1vNakYRoVhV7dwCYN7oLHXQBe7fqaYHDbUStCrGzm1rOe4jFTfOHrNIve6x4aLdW3N4M7inTdZK7v3t2_FeCbG9g06A09N75jmJ26uwcQXh7eez9nEnBrzeh7JnGA18UJsYHhpaoqftdMV52NDNIw6os7zM9352R3xEzZErK-mD0Cw42G1zr9zk_dfd0z0RyF5pr9yFVYbY9mga6_vVmBOhTsnFzPIA.4XSwi4xokumtM-w7.3sBpe1XM34pG2CkKl9XUvSLd9y2C7A4I3Nz5PNNw1ZLzGecverVYkh5HKpjH9EI-6Qv4rfovzpqh_rt-JbaBNhqU5jZgA0v4HEQJwJaY8oJ7Q8TI3oiLtqvi-r6kmXKDixSj7BbwQ5kQ2o4S9Wx13O60MtzCH7dvFryRxHYvyblvSUpSXoqKGy5Zljf7nWPLFjq2RYRG6vUHkOE1CfYO2BqoEkTILe7Eqg4sD7BiTilz2u90uGIRafxdC0PUThMfNY6zlGH0LsT9YUDmU4O2pWGz5yzHYNXKRAHRUu-Oz3KQI0FVNXdKEiQl6CWeErOxM8Efin67TKZUVx745ddL-BZGqoyaEmktu71mfRMHXX6sDBQwvQdXeZG3VpHdbqvU9ycavjsEJhnEVFBaTrpu5G-nTiX0yZKRMeIKyIr1PsoGRgqNTfL7W1lGCb68n45UNXIr2sq3eGS8arCIAPzYPszPGDkWzXNy4EF8dMY4py9ml29GLm2QTTW4rEL6d2VU-rebf5JstINVg5s-We-ugyEyBVE-03VjpZRMFkA3jMNbm_kK5UTU0bi7BYb2912wA6Mcc0wCPK_3F1pW2Zljgto1isBOk9--iR5MIuVt91rxfUs7Fzv2-wFrni2aaW1dxgIjmb_rnBlM_mH4USFtC2ueNv-Vz-QQBOm37W0I-KSXBuiDl_qUMRBDE0DKDsgyuAJ2a9dmVF9F5Oqw5wvQEtQttbJfh0RhhB8WX42kK5cNIp96da4kSxvLplPpAh33kv2WGLcjMoxnWGEdjo2e2Riz2IxWg3mMOoAoRM3uCIJUi6Z83SdmmfpCcl2uV_1ztgplmiayLpj6Pa68AxkM7wt7tASH9GcVN92zvFWgKco033RE6jRGWPNXtOhVvgQPaEUI0E4te3_CXhGB2WPmKKPIsBiBWDZFA34cVMQbUSUTfM-PwYBPdAf-.pK1LGDsQ0W12JJZLz_sD3x", "newPassword": "mynewsecurepassword" }
A successful request can have different responses depending on the result of the request. If an alternate action is not enabled, then the response will look like the following:
HTTP/1.1 200 OK Content-Type: application/json { "result": true, }
If there is an alternate action enabled, there will be a message field populated in the response, such as the following:
HTTP/1.1 200 OK Content-Type: application/json { "result": true, "message": "My alternate action message", }
If there is an error during the update password request or the alternate action fails, the request will be similar to the following. The message property will be different based on the type of error being thrown on the server.
HTTP/1.1 400 Bad Request Content-Type: application/json { "httpStatusCode": 400, "message": "Error message", }
Pictograph Authentication Method
Here is an example response from the server indicating that Pictograph authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "pictograph", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "challenge", "numToChoose": 1, "images": [ { "id": "_social-016_apple-64.png", "url":"https://rapidIdentity.example.com:8443/idp/ws/icons/ _social-016_apple-64.png" }, { "id": "_social-010_html5-64.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _social-010_html5-64.png" }, { "id": "_social-036_android-64.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _social-036_android-64.png" }, { "id": "_thin-0037_smiley_happy_like_face-48.png", "url": "https://localhost:8443/idp/ws/icons/ _thin-0037_smiley_happy_like_face-48.png" }, { "id": "_thin-0038_smiley_neutral_face-48.png", "url": "https://localhost:8443/idp/ws/icons/ _thin-0038_smiley_neutral_face-48.png" } ] } }
Note the value of the type property is pictograph and the step object has a type property value of challenge.
The numToChoose property indicates how many of the provided images the user must identify.
The images array contains a randomized subset of the total image set available to the method as defined in the Authentication Policy. It will always contain at least numToChoose images which the user previously selected during their setup step.
To successfully complete the Pictograph authentication step, the user must identify the image(s) they chose during the setup phase. The IDs of those images need to be sent to the server in the subsequent request:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "pictograph", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "challenge", "imageIds": [ "_social-016_apple-64.png" ] } }
Setup
If a user needs to choose their pictures for a future challenge, the server will respond with a setup step. It will look similar to the following:
HTTP/1.1 200 OK Content-Type: application/json { "type": "pictograph", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "setup", "numToChoose": 1, "images": [ { "id": "_social-016_apple-64.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _social-016_apple-64.png" }, { "id": "_social-010_html5-64.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _social-010_html5-64.png" }, { "id": "_social-036_android-64.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _social-036_android-64.png" }, { "id": "_thin-0037_smiley_happy_like_face-48.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _thin-0037_smiley_happy_like_face-48.png" }, { "id": "_thin-0038_smiley_neutral_face-48.png", "url": "https://rapidIdentity.example.com:8443/idp/ws/icons/ _thin-0038_smiley_neutral_face-48.png" } ], "passwordRequired": true } }
The numToChoose property indicates how many images the user must choose for future challenges.
The images array contains all of the possible images the user may choose. Each image has an id and a url.
The passwordRequired property indicates whether or not a valid password is required to complete the setup process. This will be true if there have been no previous authentication steps which have validated the user is who they claim to be. In other words requiring a password for setup ensures that someone cannot setup Pictograph authentication for someone else by simply supplying a valid username at the beginning of the process.
To successfully complete the setup step the proper number of images must be chosen and their IDs should be passed to the server.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "pictograph", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "setup", "imageIds": [ "_social-016_apple-64.png" ], "password": "idAuto#123" } }
PingMe Authentication
Here is an example response from the server indicating that PingME authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "pingMe", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "chooseIdentity", "identities": [ { "username": "username1", "domain": "DOMAIN1" }, { "username": "username2", "domain": "DOMAIN2" } ] } }
Note the value of the type property is pingMe and the step object has a type property value of chooseIdentity.
The identities array will contain one or more identities associated with this user which they can choose to use for this authentication step. An identity object consists of two properties: username and domain. The username property will always be present but the domain property might not. When displaying the identity choice to the user, if a domain value is present, it should be displayed in standard Windows format: domain\username.
Currently, the first step for PingME authentication will always be chooseIdentity even if the authenticating user can use a single identity. We could go a few different ways with this.
The UI could just immediately begin the authentication process by sending a chooseIdentity request to the server with the single identity without user interaction
The UI could present a button that the user should click when they are ready for RapidFederation to send the authentication request to their device
The server could be changed to skip the initial chooseIdentity step and automatically send the authentication request (perhaps this could be a configurable setting in the policy).
To begin authentication, the user must choose an identity to use and the following request should be issued:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "pingMe", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "chooseIdentity", "identity": { "username": "username1", "domain": "DOMAIN1" } } }
If everything is good so far, the server sends back a response indicating that authentication is underway:
HTTP/1.1 200 OK Content-Type: application/json { "type": "pingMe", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "authenticating" } }
At this point, the user should receive the push notification on their device and they can Approve or Deny the request. However, while that's happening, the UI should display a spinner and poll the server in the background every few seconds to find out if the authentication has succeeded or failed.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "pingMe", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "step": { "type": "pollAuthentication" } }
RapidFederation will continue to respond to pollAuthentication requests with authenticating responses until the 2FA ONE server sends back a response or 120 seconds has elapsed.
I have been told that the 2FA ONE server will always return a response within a minute, but we give it up to two minutes
If the user approved the push request on their device and RapidFederation successfully receives that response, then the authentication flow will continue to the next step.
Authentication Failure
If authentication fails because the user denied the push request on their device or the request times out without a response from the user, then authentication has failed. In this case the response from the server will resemble the following:
HTTP/1.1 200 OK Content-Type: application/json { "type": "pingMe", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "error": { "type": "simple", "message": "2FA ONE PingME Authentication Failed" }, "step": { "type": "chooseIdentity", "authenticationRetries": 2, "identities": [ { "username": "username1", "domain": "DOMAIN1" }, { "username": "username2", "domain": "DOMAIN2" } ] } }
Please note that the response contains a standard simple type error object with a message with should be displayed to the user. Additionally, the chooseIdentity step contains a new property authenticationRetries which indicates how many more PingME authentication attempts may be made before authentication fails altogether.
Since this response step type is chooseIdentity, this gives the user the opportunity to use a different identity for the next authentication attempt.
Useful WSDLs for the RapidIdentity MFA server:
Portal Challenge Authentication Method
If Federation calls out to retrieve the challenge set from Portal and challenge questions are either out of date or not setup, Federation will initiate the Portal challenge authentication setup.
Here is an example setup response from the server indicating that Portal challenge authentication setup is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "portalChallenge", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "step": { "type": "setup", "challengeSetup": { "targetId": "", "challengePolicy": { "id": "", "name": "", "noChallenge": false, "adminQuestions": [ { "required": true, "question": "What is your favorite color" }, { "required": true, "question": "What is your mother's maiden name" } ], "minAdminQuestionPoolSize": 2, "allowUserDefinedQuestions": true, "minUserQuestionPoolSize": 0, "maxUserQuestionPoolSize": 255, "minQuestionLength": 3, "maxQuestionLength": 255, "minAnswerLength": 3, "maxAnswerLength": 255, "numAdminAnswersForAuth": 2, "numUserAnswersForAuth": 0, "numHelpdeskQuestions": 0, "restrictWordsFromQuestion": false, "canSkipSetup": false, "enforceUniqueAnswers": true }, "adminQuestions": [ { "required": true, "question": "What is your favorite color" } ], "userQuestions": [], "helpdeskQuestions": [] }, "passwordRequired": false } }
Note that the value of the type property is portalChallenge and the step type is setup.
In addition to sending the standard id, type, and step properties with the next request, answers must be provided for all values in the challengeQuestions array from the server response:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "portalChallenge", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "step": { "type": "setup", "adminQuestions": [ { "question": "What is your favorite color", "answer": "cyan" }, { "question": "What is your mother's maiden name", "answer": "smith" } ], "userQuestions": [], "helpdeskQuestions": [] } }
Challenge:
If Federation calls out to retrieve the challenge set from Portal and challenge questions valid, Federation will initiate the Portal challenge authentication setup.
Here is an example challenge response from the server indicating that Portal challenge authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "portalChallenge", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "step": { "type": "challenge", "challengeQuestions": [ "What is your favorite color", "What is your mother's maiden name" ] } }
Note that the value of the type property is portalChallenge and the step type is challenge.
In addition to sending the standard id, type, and step properties with the next request, a correct answer must be provided for all values in the challengeQuestions array from the server response:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "portalChallenge", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "step": { "type": "challenge", "questionsAndAnswers": [ { "question": "What is your favorite color", "answer": "cyan" }, { "question": "What is your mother's maiden name", "answer": "smith" } ] } }
Errors
If Federation calls out to retrieve the challenge set from Portal and that request fails, either because Portal could not be contacted or the user's password could not be retrieved from the directory, the authentication process will immediately fail. It will look something like this:
HTTP/1.1 200 OK Content-Type: application/json { "type": "fail", "id": "931c4a40-2dc9-11e6-937b-005056c00008", "error": { "type": "simple", "message": "Failed to retrieve a Portal challenge" } }
QR Code Authentication Method
The QR Code authentication method is a bit different from the other methods so far because it can be used to initiate the authentication process as well as provide another factor after authentication has been initiated via standard Initialization schemes.
As Initialization
At the API level, you know that a QR code may be used to initialize the authentication process if the response from the initialization request contains the property allowQRCodeScan with a value of true.
Currently, there are to ways for this to happen:
If there is at least one enabled Authentication Policy whose first enabled method is QR Code
If there is at least one enabled Authentication Policy whose insecureQRIdEnabled flag is set to true
HTTP/1.1 200 OK Content-Type: application/json { "type": "username+password", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "allowQRCodeScan": true, "claimAccountLink": { "href": "/arms/claim/", "displayName": "Claim My Account" }, "helpLinks": [ { "href": "/arms/forgotmyusername", "displayName": "Forgot My Username" }, { "href": "/arms/forgotmypassword?redirect_to=/arms", "displayName": "Forgot My Password" } ] }
To successfully initialize the authentication process with a QR code, the client must send a request containing the value encoded by the QR Code as read by a scanner:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "qrCode", "id": "35bf1450-2dbe-11e6-8a8b-005056c00008", "value": "gobbledygookgibbersih" }
As an Authentication Step
Here is an example response from the server indicating that QR Code authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "qrCode", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008" }
To successfully complete the QR code authentication step, the client must send a request containing the value encoded by the QR Code as read by a scanner:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "qrCode", "id": "e89afb10-2e6e-11e6-b6f0-005056c00008", "value": "gobbledygookgibbersih" }
SMS Authentication Method
Here is an example response from the server indicating that SMS authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "sms", "id": "beaa50c0-4a9a-11e5-ae5f-0050b6c32ffc" }
This indicates that RapidFederation was able to successfully call out to the SMS provider to send a One-Time Password (OTP) to the user's mobile device.
In addition to sending the standard id and type properties with the next request, the otpCode should be included with the value the user received on their device.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "sms", "id": "beaa50c0-4a9a-11e5-ae5f-0050b6c32ffc", "otpCode": "123456" }
Re-sending the OTP
Please note that this will negate the original code and in the event that the user receives both codes, the latest one is the only one which will work.
If the user wishes for RapidFederation to re-send the OTP code to their device the following request can be made:
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "sms", "id": "beaa50c0-4a9a-11e5-ae5f-0050b6c32ffc", "forceNewAuthz": true }
Social Authentication Method
Setup
Log in to https://developers.facebook.com
My Apps -> Add a New App -> Website
Give it a meaningful name like "RapidFederation Test" -> Create New Facebook App ID
Settings -> Advanced -> Valid OAuth redirect URIs
https://<RF_HOST>:<RF_PORT>/idp/socialCallback?n=facebook
Settings -> Advanced -> Require App Secret
Set to "No"
Enter App ID and App Secret in the Social configuration for your Authentication Policy
Log into Log into https://console.developers.google.com
Create a new Project and give it a meaningful name like "RapidFederation Test"
Choose "Use Google APIs"
Search for and enable Identity Toolkit API
Choose the "Credentials" item on the left
Add credentials
OAuth 2.0 client ID
Configure consent screen -> Save
Application Type: Web Application
Authorized redirect URIs
https://<RF_HOST>:<RF_PORT>/idp/socialCallback?n=googleplus
Create
Enter client ID and client secret in the Social configuration for your Authentication Policy
Log into https://apps.twitter.com/
Create New App
Give it a meaningful name like "RapidFederation Test"
Fill in the rest of the required fields
Callback URL
https://<RF_HOST>:<RF_PORT>/idp/socialCallback/twitter
If testing with localhost, just put in another hostname. It will be OK
Permissions -> Read only
Enter Consumer Key and Consumer Secret in the Social configuration for your Authentication Policy
Create Application
Give it a meaningful name like "RapidFederation Test"
Fill in the rest of the required fields
Keep Default Application Permission of r_basicprofile
OAuth 2.0 Authorized Redirect URLs
https://<RF_HOST>:<RF_PORT>/idp/socialCallback?n=linkedin
Enter Client ID and Client Secret in the Social configuration for your Authentication Policy
API
Initial Response
Below is an example of an initial response:
{ "type": "social", "id": "c2e109d0-8d7b-11e5-8c0d-0050b6c32ffc", "step": { "type": "choose", "providers": [ { "id": "facebook", "iconUrl": "https://rapidIdentity.example.com:8443/idp/assets/img/ social/facebook.svg", "authenticationUrl": "...." }, { "id": "googleplus", "iconUrl": "https://rapidIdentity.example.com:8443/idp/assets/img/ social/googleplus.svg", "authenticationUrl": "...." }, { "id": "linkedin", "iconUrl": "https://rapidIdentity.example.com:8443/idp/assets/img/ social/linkedin.svg", "authenticationUrl": "...." }, { "id": "twitter", "iconUrl": "https://rapidIdentity.example.com:8443/idp/assets/img/ social/twitter.svg", "authenticationUrl": "...." } ] } }
This is an example of a "type" = "social" response from the server. Notice the "step" object whose type is "choose". This object contains information about all of the choices the user has for social authentication – in other words, which providers (social networks) are allowed for authentication. Each provider has an "id", an "iconUrl" and an "authenticationUrl". The choose screen should render each option as a clickable button with the specified iconUrl as the button's image.
When the user clicks on one of them, a new tab should be opened to the associated "authenticationUrl". This will redirect the user to that social platform for authentication and once authenticated, back into RapidFederation at the "callback URL" of .../idp/socialCallback?n=<network>
.
Auth Step
As soon as the user clicks the button to open the new tab, the RapidFederation page should switch to a view that is ready to submit the "auth" step.
Below is an example auth request:
{ "type": "social", "id": "c2e109d0-8d7b-11e5-8c0d-0050b6c32ffc", "step": { "type": "auth" } }
kThe "auth" step is intended to be submitted after authentication at the social site has completed. If it is submitted before that takes place, the "choose" step will be returned again.
If the user authenticates to the social platform with an identity which has already been paired, then at this point life is good and RapidFederation will move on to the next step. If the user authenticates with a new identity (i.e. one which they have not previously paired), then we move on to the "pair" step which begins with a "pair" response from the server.
Pair Step
Below is an example pair response:
{ "type": "social", "id": "c2e109d0-8d7b-11e5-8c0d-0050b6c32ffc", "step": { "type": "pair", "provider": { "id": "facebook", "iconUrl": "https://localhost:8443/idp/assets/img/social/googleplus.svg" }, "profile": { "name": "John ", "email": "jdoe@example.com", "imageUrl": "" }, "pairRequiresPassword": true } }
The "pair" begins with the server responding with some basic information about the social identity used for authentication and should be considered as the server confirming that the user wants to pair that social identity with their RapidFederation identity. Note that there is information about the provider and some basic profile information.
In my testing with our currently supported social networks, I was able to get at least "name" and "imageUrl" to be returned. Realize that the information we get back from each provider is dependent on what information the user has given to that provider as well as what OAuth permissions the app on that platform has been given.
One more request is required to complete the pair process and that is the confirmation from the user that they want to pair with that social identity:
Pair Request
Below is an example pair request:
{ "type": "social", "id": "c2e109d0-8d7b-11e5-8c0d-0050b6c32ffc", "step": { "type": "pair", "password": "P@$$w0rD" } }
If "pairRequiresPassword" is true in the previous Pair Response, then of course the user will need to provide their password to complete the pair. Otherwise it can be omitted. Once complete RapidFederation moves on to the next authentication step.
TOTP Authentication Method
Here is an example response from the server indicating that TOTP authentication is required as the next step:
HTTP/1.1 200 OK Content-Type: application/json { "type": "totp", "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "allowDeferral": true }
Note that the value of the type property is totp.
When responding to the TOTP challenge a value for the otpCode property is required. This should contain the current value as displayed on the TOTP device. Additionally, if the response from the server contains a true value for the allowDeferral property, as above, the user may opt to defer being challenged for 30 days.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "totp", "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "otpCode": "123456", "defer": true }
Deferral
If deferral is allowed and opted-into by the user, if the otpCode was valid then the next response from the server will contain a Set-Coolie header which should be handled automatically by the browser if cookies are enabled. The cookie contains information linking a particular user to a particular deferral.
Since the deferral is managed with a cookie, it is only good for a single browser on a single device. If a different browser or device is used in the future, the user will be challenged again and may opt-in to deferral for that device/browser combination.
Multiple users may have active deferrals on the same device & browser.
Setup
The first time a user is challenged for TOTP authentication they need to go through a setup phase where they register their TOTP key with a device. In this case, the server will respond with a setup object which will contain all of the information required.
Note
Displayed values have been truncated here for formatting purposes, but the strings listed here should represent actual, usable values when generated in a production environment.
HTTP/1.1 200 OK Content-Type: application/json { "type": "totp", "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "setup": { "setupInstructions": "You need to set this up now!", "base64QrCode": "iVBORw0KGgoAAAANSUhEUgAAASwAAAEsAQAAAABRB[...]", "secret": "KDXUAAZNFCYVUEVXPXPT3BHRX4S5KXFO", "passwordRequired": false }, "allowDeferral": true }
The setupInstructions property contains instructions which should be displayed to the user
The base64QrCode property contains a Base64-encoded PNG image of the QR code which should be displayed. Many TOTP devices allow registration by scanning a QR code.
The secret roperty contains the TOTP secret key which can be used to perform manual registration on a device
The passwordRequired property indicates whether or not a valid password is required to complete the setup process. This will be true if there have been no previous authentication steps which have validated the user is who they claim to be. In other words requiring a password for setup ensures that someone cannot setup TOTP authentication for someone else by simply supplying a valid username at the beginning of the process.
To To successfully complete the setup step a valid otpCode must be provided. This ensures that the user has successfully setup their TOTP device.
POST /idp/ws/rest/authn HTTP/1.1 Content-Type: application/json Accept: application/json { "type": "totp", "id": "e230e2e0-25ae-11e5-8dc9-0050b6c32ffc", "otpCode": "123456", "defer": true, "password": "mysupersecretpassword" }
RapidIdentity API Reference
Swagger API Documentation
For anyone with the API Developer Role, the Swagger-defined APIs can be accessed by following these three steps.
Open a browser tab and type this address: https://<hostname or IP address>/api.
Click the Swagger link, which will be in this format: https://<hostname or IP address>/api/rest/api-docs?url=/api/rest/swagger.json.
Note
This URL can be bookmarked for convenience.
The Swagger-defined APIs may take a moment to load. This behavior is normal and expected. Once loaded, the APIs appear as shown.