Trust SSO v2
Table of content
- Implementation
- Assetlinks
- Trust IDP
- Trust Transaction
- Trust Validation
- Trust FIDO2
- Trust Native
- Errors
- Logs
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
Name | Description | Default Value | Optional |
---|---|---|---|
scheme | Specifies the scheme | https | Yes |
baseUrl | Specifies the domain | atenea.trust.lat | Yes |
scopes | Specifies the scopes | - | No |
acrValue | Specifies the acr value | - | No |
clientID | Set the client id | - | No |
clientSecret | Set the cliend secret | - | Yes |
redirectUri | Set the register redirect URI | - | No |
responseType | Specifies the response type | - | No |
grantType | Specifies the grand type | - | No |
state | Random number in openid connect | - | No |
tokenPath | Specifies the token path | token | Yes |
authPath | Specifies the auth path | authorize | Yes |
userInfoPath | Specifies the user info path | userinfo | Yes |
appendPath | Append a Path to URL | - | No |
build | Return 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
Name | Value |
---|---|
AUTHORIZATION_CODE | authorization_code |
IMPLICIT | implicit |
CLIENT_CREDENTIALS | client_credentials |
REFRESH_TOKEN | refresh_token |
AUTHORIZATION_CODE | refresh_token |
DEVICE_CODE | device_code |
PKCE | pkce |
GRANT_TYPE | grant_type |
CODE | code |
ID_TOKEN | id_token |
TOKEN | response_type |
AUTH | auth |
AUTHORIZE | authorize |
USERINFO | response_type |
OAUTH2 | oauth2 |
HTTP | http |
HTTPS | https |
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
Name | Description | Default Value | Optional |
---|---|---|---|
scopes | Specifies the scopes | - | No |
clientID | Set the client id | - | No |
clientSecret | Set the cliend secret | - | No |
redirectUri | Set the register redirect URI | - | Yes |
responseType | Specifies the response type | - | Yes |
grantType | Specifies the grand type | - | No |
build | Return 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
Code | Value |
---|---|
0 | Unknow error |
400 | Bad request |
401 | The request was unauthorized |
403 | The request was forbidden |
404 | The requested could not be found |
405 | Method not allowed |
500 | Internal server error |
501 | Not implemented |
502 | Bad gateway |
503 | Service unavailable |
1000 | Null or empty data |
1001 | Null response body from server |
1002 | Unexpected parameter or value |
1003 | Error network connection |
1004 | Error intent |
1005 | Error 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":[]}
└──────────────────────────────────────────────────────────────────────────────────