This integration utilizes LoginID's client and backend SDKs to implement FIDO registration and authentication. This document assumes familiarity with the FIDO process. The integration to the ONEtech platform is specific to the app domain and all necessary configurations (clientIDs, private keys, etc.) are attached to the app's domain name and stored in the cluster. A ONEtech WorkflowAPI JWT that contains the correct domain is needed in all calls to the REST API as they will look up the necessary config using the domain property.
A number of different tokens may be referred to:
WORKFLOWAPI_TOKEN
: This is the ONEtech WorkflowAPI JWT that we use on the platform.SERVICE_TOKEN
: This service token is generated using the private key stored in-cluster. This is needed to communicate with LoginID's REST API.CREDENTIAL_TOKEN
: This JWT is obtained by the client when they successfully authenticate and can be passed along with any workflow calls and can be verified that the caller is the authenticated user.
A new user account can be created using either "Register With FIDO"
or "Register With Password"
. On successful completion the user's credential object can be obtained using the client store's bindable prop getFidoCredential()
which will contain a CREDENTIAL_TOKEN
which can be sent along with any workflow calls and used to verify the user using the /verify-credential-token
REST API endpoint. This credential object can be stored locally on the client and checked first in the future to allow a user to remain logged in.
An existing user can authenticate and log in using either "Authenticate With FIDO"
or "Authenticate With Password"
. On successful completion the user's credential object can be obtained using the client store's bindable prop getFidoCredential()
which will contain a CREDENTIAL_TOKEN
which can be sent along with any workflow calls and used to verify the user using the /verify-credential-token
REST API endpoint. This credential object can be stored locally on the client and checked first in the future to allow a user to remain logged in.
An existing user can authorize a new device to access their account by either attempting to log in using their new device first or by pre-emptively requesting an authorization code.
In either scenario the workflow must call the /generate-auth-code
REST API endpoint with the purpose
property set as "add_credential"
and the resulting auth code must be sent to the user either through an external communication channel (email or SMS) or directly in the app on a previously authorized device. Before that code can be used though, the end user must first use a previously authorized device to pass in their CREDENTIAL_TOKEN
to the /authorize-code
REST API endpoint with the purpose
property set as "add_credential"
. The reason for this is to disallow anonymous parties to request authorization and intercept and use the code to gain access. The code must be approved by the authenticated user.
Finally, the authorized code can be used in "Add FIDO Credential"
on the new device. A credential name can be specified to allow the user to manage which devices can continue to have access to their account.
This flow is similar to the last one but will not result in the new device being added to the user account's list of credentials. As in the previous flow, a call must be made to /generate-auth-code
with the purpose
property set as "temporary_authentication"
and that code must be authorized by an authenticated user with /authorize-code
passing in a CREDENTIAL_TOKEN
and, again, with the purpose
property set as "temporary_authentication"
.
On the new device that's being used to access the account temporarily, the "Request Temporary Authentication"
Client Store action can be called using the username
and code
. This call will wait until the code has been authorized by an authenticated device for 2 minutes until the code times out. Once the code has been authorized the store action will return the user's credential object which can be retrieved with getFidoCredential()
. In this case, it is not recommended to store the user credential object locally on the temporary device.
This flow should be used sparingly and only in the case that a user has lost access to all previously authenticated devices as it bypasses the manual code authorization step from the authenticated user. A call can be made to /generate-recovery-code
which will generate a pre-authorized code which needs to be sent to the user using external secure communication channels such as a verified email.
LoginID has several HTTP REST API calls that lets us manage user accounts. They can be found at LoginID API and require a SERVICE_TOKEN
in the Authorization header which can be requested from the /generate-service-token
endpoint. A service token needs to be generated with the specific scope required in the call and the scopes can be found here: LoginID Service Token Scopes
initLoginId()
registerWithFido(username: string)
registerWithPassword(username: string, password: string, confirmPassword: string)
authenticateWithFido(username: string)
authenticateWithPassword(username: string, password: string)
addFidoCredential(username: string, code: number, credentialName: string)
requestTemporaryAuthentication(username: string, code: number)
Endpoint: https://loginid.onetechnology.com/generate-service-token
Header: Authorization: Bearer {{WORKFLOWAPI_TOKEN}}
Payload:
{
"scope": "code.generate",
"username": "itskhanow",
"userid": "c80af3e6-2660-43a3-a1c1-7bf679299cba"
}
Response:
{{SERVICE_TOKEN}}
Work In Progress
Endpoint: https://loginid.onetechnology.com/verify-credential-token
Header: Authorization: Bearer {{WORKFLOWAPI_TOKEN}}
Payload:
{
"credentialToken": "{{CREDENTIAL_TOKEN}}",
"username": "itskhanow"
}
Response:
{
"iss": "loginid.io",
"sub": "c80af3e6-2660-43a3-a1c1-7bf679299cba",
"sid": "9b9cd28c-1df1-49f4-a2ac-379086475a5e",
"nid": "c33ddede5085b9ea",
"aud": "Uz1cZDo7jWdS4c7ta2hhHq4KDbLLCvrXxPpx20zd1ihlXfvcw4a1drkjwTUHU8FWnzGNYVOaQPj5mo5qTwIO2Q",
"action": "login",
"iat": 1641426887,
"udata": "itskhanow"
}
Endpoint: https://loginid.onetechnology.com/generate-auth-code
Header: Authorization: Bearer {{WORKFLOWAPI_TOKEN}}
Payload:
{
"username": "itskhanow",
"codeType": "short || long || phrase (optional)",
"purpose": "temporary_authentication || add_credential"
}
Response:
{
"code": "527603",
"expires_at": "2022-01-14T04:48:31Z",
"is_authorized": false
}
Endpoint: https://loginid.onetechnology.com/authorize-code
Header: Authorization: Bearer {{WORKFLOWAPI_TOKEN}}
Payload:
{
"credentialToken": "{{CREDENTIAL_TOKEN}}",
"username": "itskhanow",
"code": 527603,
"codeType": "short || long || phrase (optional)",
"purpose": "temporary_authentication || add_credential"
}
Response:
{
"expires_at": "2022-01-14T04:48:31Z",
"is_authorized": true
}
Endpoint: https://loginid.onetechnology.com/generate-recovery-code
Header: Authorization: Bearer {{WORKFLOWAPI_TOKEN}}
Payload:
{
"username": "itskhanow"
}
Response:
{
"code": "679146",
"expires_at": "2022-01-14T04:41:12Z",
"is_authorized": true
}
getFidoSupport()
returns true/false
getFidoCredential()
returns
{
"is_authenticated": true,
"client": {
"id": "Uz1cZDo7jWdS4c7ta2hhHq4KDbLLCvrXxPpx20zd1ihlXfvcw4a1drkjwTUHU8FWnzGNYVOaQPj5mo5qTwIO2Q",
"type": "directweb",
"rp_id": "khanvideorecordertest.onetechnology.com"
},
"user": {
"id": "c80af3e6-2660-43a3-a1c1-7bf679299cba",
"username": "itskhanow",
"namespace_id": "c33ddede5085b9ea",
"type": "regular"
},
"credential": {
"uuid": "61b57503-8b42-47d1-8b5f-a48bd2a15566",
"name": "Linux (Chrome) - 61b57503",
"type": "password"
},
"jwt": "{{CREDENTIAL_TOKEN}}"
}
onLoginIdInit
onRegisterWithFido
onRegisterWithPassword
onAuthenticateWithFido
onAuthenticateWithPassword
onAddFidoCredential
onTemporaryAuthentication