Skip to main content

Trust SSO v2

Table of content#

Implementation#

To enable the retrieval of Trust Technologies hosted packages via Gradle, the first step is to add your repository to the build.gradle file (project level).

To do add the following, at any location, to your build.gradle file:

repositories {
maven {
url "https://dl.cloudsmith.io/OZ4Ow2XY7HBOezgN/trusttechnologies/ssov2/maven/"
}
}

After the repository is added to the build.gradle file, all that is left is to specify the dependency in the dependencies section of the project build.gradle file (app level).

To do this add the below to your build.gradle file (app level):

dependencies {
implementation 'com.sdk.trust:sso:0.0.14'
}

Assetlinks#

To use FIDO2 API on an TrustSSO , associate it with a website and share credentials between them. To do so, leverage the Digital Asset Links. You can declare associations by hosting a Digital Asset Links JSON file on your website, and adding a link to the Digital Asset Link file to your app's manifest.

Host .well-known/assetlinks.json at your domain#

You can define an association between your app and the website by creating a JSON file and put it at .well-known/assetlinks.json. Luckily, we have a server code that displays assetlinks.json file automatically, just by adding following environment params to the .env file in glitch:

  • ANDROID_PACKAGENAME: Package name of your app (com.example.android.fido2)
  • ANDROID_SHA256HASH: SHA256 Hash of your signing certificate

In order to get the SHA256 hash of your developer signing certificate, use the command below. The default password of the debug keystore is "android".

keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore

Note: In some cases you have to remove the command -exportcert

assetlinks.json example#

[
{
"relation": [
"delegate_permission/common.handle_all_urls",
"delegate_permission/common.get_login_creds"
],
"target": {
"namespace": "web",
"site": "https://<your-domain>.com"
}
},
{
"relation": [
"delegate_permission/common.handle_all_urls",
"delegate_permission/common.get_login_creds"
],
"target": {
"namespace": "android_app",
"package_name": "you.app.bundle.id",
"sha256_cert_fingerprints": [
"DE:AD:BE:EF:..."
]
}
}
]

Trust IDP#

The TrustID class provides the facility to initiate a login flow from another platform under the OpenID Connect standards.

Builder#

NameDescriptionDefault ValueOptional
schemeSpecifies the schemehttpsYes
baseUrlSpecifies the domainatenea.trust.latYes
scopesSpecifies the scopes-No
acrValueSpecifies the acr value-No
clientIDSet the client id-No
clientSecretSet the cliend secret-Yes
redirectUriSet the register redirect URI-No
responseTypeSpecifies the response type-No
grantTypeSpecifies the grand type-No
stateRandom number in openid connect-No
tokenPathSpecifies the token pathtokenYes
authPathSpecifies the auth pathauthorizeYes
userInfoPathSpecifies the user info pathuserinfoYes
appendPathAppend a Path to URL-No
buildReturn a instance of TrustIDP-No

Note: Redirect URI must be registered in the manifest as a deep link associated with an activity, for more information see the deep link documentation

Code Example#

val trustidp = TrustIDP.Builder(context)
.scopes("<YOUR_SCOPES>")
.acrValue(AcrValue.AUTOIDENTIFY)
.clientID("<YOUR_CLIEND_ID>")
.redirectUri("<YOUR_REDIRECT_URI>")
.clientSecret("<YOUR_CLIEND_SECRET>")
.responseType(ResponseType.CODE)
.grantType(GrantType.AUTHORIZATION_CODE)
.build()
trustidp.requestAuthorize()

Methods#

Request Authorize#

Open a web browser to login in atenea IdP (default), the result data will be returned in the activity callback as a intent

fun requestAuthorize(){}

Get Code#

Get the code as a string from the intent obtained in the callback activity

fun getCode(intent: Intent):String{}

Intent: the intent of the callback return the code as String

Token Exchange#

Exchange the code obtained in the activity callback for an access token

fun tokenExchange(intent: Intent, listener: TrustListenerSSO<TokenResponse>){}

Intent: the intent of the callback Listener: Listener to get the access token information

Get User Info#

Get user data by access token

fun getUserInfo(listener: TrustListenerSSO<UserInfoAtenea>){}

Listener: Listener to get the user information

User info object#

data class UserInfoAtenea(
val companyUid: String,
val dni: String,
val email: String,
val lastName: String,
val name: String,
val sub: Int
)

Refresh Token IDP#

Refresh token for access token

fun refreshToken(listener: TrustListenerSSO<TokenResponse>){}

Listener: Listener to get the access token information

Constants#

Constants that can be used in the creation of the builder

NameValue
AUTHORIZATION_CODEauthorization_code
IMPLICITimplicit
CLIENT_CREDENTIALSclient_credentials
REFRESH_TOKENrefresh_token
AUTHORIZATION_CODErefresh_token
DEVICE_CODEdevice_code
PKCEpkce
GRANT_TYPEgrant_type
CODEcode
ID_TOKENid_token
TOKENresponse_type
AUTHauth
AUTHORIZEauthorize
USERINFOresponse_type
OAUTH2oauth2
HTTPhttp
HTTPShttps

Trust Transaction#

Methods#

Get Transaction#

TrustTransactions().getTransaction("5cff60", object : TrustListenerSSO<TransactionResponse> {
override fun onSuccess(code: Int, data: TransactionResponse) {
//code from server
// data from serve
}
override fun onError(code: Int, msg: String) {
//code from server
//error from server
}
})

Update Transaction#

val updateTransactionRequest = UpdateTransactionRequest("5cff60", false, "sms", true)
TrustTransactions().updateTransaction(
updateTransactionRequest, object : TrustListenerSSO<TransactionResponse> {
override fun onSuccess(code: Int, data: TransactionResponse) {
//code from server
// data from serve
}
override fun onError(code: Int, msg: String) {
//code from server
//error from server
}
})

Get Transaction By Company#

TrustTransactions().getTransactionByCompany("5cff60", object : TrustListenerSSO<TransactionResponse> {
override fun onSuccess(code: Int, data: TransactionResponse) {
//code from server
// data from serve
}
override fun onError(code: Int, msg: String) {
//code from server
//error from server
}
})

Trust Validation#

Methods#

Validate Code#

val validateTransactionRequest = ValidateTransactionRequest("user_id","transaction_Id")
TrustValidation().validateCode(validateTransactionRequest: ValidateTransactionRequest, listener: TrustListenerSSO<TransactionResponse>)

Description#

Validate an OTP code

Validate QR Code#

val validateTransactionRequest = ValidateTransactionRequest("user_id","transaction_Id")
TrustValidation().validateQr(validateTransactionRequest: ValidateTransactionRequest, listener: TrustListenerSSO<TransactionResponse>)

Description#

Validate an QR code

Validate Login Assisted#

val validateTransactionRequest = ValidateTransactionRequest("user_id","transaction_Id")
TrustValidation().validateLoginAssisted(validateTransactionRequest: ValidateTransactionRequest, listener: TrustListenerSSO<TransactionResponse>)

Trust FIDO2#

Allows the user to implement security to their transactions through the security of the mobile device

Methods#

Register Request#

fun registerRequest(registerRequest: RegisterRequest, context: Context)

Description#

Register Request is the method that is called when the FAB is pressed. We'd like to make this method call the server API . The API returns an ApiResult with all the PublicKeyCredentialCreationOptions that the client needs to generate a new credential.

Register Response#

Description#

fun registerResponse(intentResult: Intent?,listener: TrustListenerSSO<RegisterResponseResponse>?)

Sign In Request#

Description#

fun signInRequest(signInRequest: SignInRequest, context: Context)

Sign In Response#

Description#

fun signInResponse(intentResult: Intent,listener: TrustListenerSSO<SignInResponseResponse>?)

Handle Error Response#

Description#

fun handleErrorResponse(errorBytes: ByteArray)

Trust Native#

Allows to obtain a login and a validation through an otp to obtain an access token through PKCE

Builder#

NameDescriptionDefault ValueOptional
scopesSpecifies the scopes-No
clientIDSet the client id-No
clientSecretSet the cliend secret-No
redirectUriSet the register redirect URI-Yes
responseTypeSpecifies the response type-Yes
grantTypeSpecifies the grand type-No
buildReturn a instance of TrustNative-No

Code example#

private val native = TrustNative.Builder()
.clientSecret(<YOUR_CLIENT_SECRET>)
.scope(<YOUR_SCOPES>)
.clientID(<YOUR_CLIENT_ID>)
.build()
native.doLogin(object : TrustListenerSSO<FormResponse>{})

Methods#

Do Login Assisted#

native.doLoginAssisted(object: TrustListenerSSO<InitFlowResponse>{})

Get Form#

native.getForm(object : TrustListenerSSO<FormResponse>{})

Description#

It returns a login type form if it is the first time it is instantiated, otherwise it will return a code form.

view_type.login_form: Means that the form that has been returned is of type login, the data of this form must be sent in the following steps view_type.code_form: Means that the form that has been returned is of type code, the data of this form must be sent in the following steps, the codes are obtained by sms, whatsapp and mail.

Login form example#
{
"data": {
"view_type": "login_form",
"fields": [
{
"name": "email",
"type": "mail"
},
{
"name": "password",
"type": "password"
}
]
}
}
Code form example#
{
"data": {
"view_type": "code_form",
"fields": [
{
"name": "a2f",
"type": "number"
}
]
}
}

Send Form#

native.sendForm(formData: JsonObject, object : TrustListenerSSO<StepsResponse> {})

Example of JsonObject#

val jsonRequest = JsonObject()
jsonRequest.addProperty("email", "mail@example.com")
jsonRequest.addProperty("password", "12312313")
jsonRequest.addProperty("a2f", "909090")

Description#

next_step: true : Means that there is still one form to complete. next_step: false : Means that there are no more forms left to complete. token_available: false: Means can't get token token_available: true: Means token can be obtained

Form step true#

{
"data": {
"next_step": true,
"token_available": false
}
}

Form step false#

{
"data": {
"next_step": false,
"token_available": true
}
}

Send Form Login Assisted#

Description#

Send a login to be authorized from another app

native.sendFormLoginAssisted(deviceCode: String, transactionId: String, object: TrustListenerSSO<StepsResponse>{})

Inject Flow#

Description#

Inject a step for the flow, the avaliable types of steps to be injected are:

NativeFlowTypes.REGISTER NativeFlowTypes.PASSWORD_RESET

native.injectFlow(
flowType: NativeFlowTypes,
listener: TrustListenerSSO<InjectFlowResponse>
)

Get Token Native#

native.getAccessToken(object : TrustListenerSSO<TokenPKCEResponse> {})

Description#

id_token: It is a jwt with the user information

{
"access_token": "dJflShMZsv1AYhttHPwUBI",
"refresh_token": null,
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InB1YmxpYzozODYwN",
"token_type": "Bearer",
"expires_in": 3600
}

Refresh Token#

Refresh token for access token

fun refreshToken(listener: TrustListenerSSO<TokenPKCEResponse>){}

Errors#

Possible errors that can be found when integrating the SDK

CodeValue
0Unknow error
400Bad request
401The request was unauthorized
403The request was forbidden
404The requested could not be found
405Method not allowed
500Internal server error
501Not implemented
502Bad gateway
503Service unavailable
1000Null or empty data
1001Null response body from server
1002Unexpected parameter or value
1003Error network connection
1004Error intent
1005Error response from fingerprint

Logs#

The logs can only be seen in the debug environment and through the TAG "PRETTY_LOGGER" to see the logs of the calls to the server, they can be seen through the TAG OkHttpClient

Log example#

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Thread: main
β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
β”‚ ErrorManagerKt.objectToJsonError (ErrorManager.kt:122)
β”‚ TrustLog.e (TrustLog.kt:16)
β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„
β”‚ {"errorCode":1000,"errorMessage":"ID must not be null or empty","stackTrace":[]}
└──────────────────────────────────────────────────────────────────────────────────
Last updated on by fcaro