Skip to main content

SSO Integration in IOS

Trust SSO - iOS

Description

TrustSSO allows client applications to fetch and update transactions and their different matters & present users different kind of authentication methods based on their needs.

Table of contents


Implementation

Easiest way to install TrustSSO is by using Cocoapods within just a few steps:

  1. Initialize cocoapods in your project (if it's not already done):
pod init

this would generate a Podfile and Pods folder.

  1. Complete Podfile according to your needs:
platform :ios, '13.0'

# this indicates the source where Cocoapods would find the pod to install
source 'https://gitlab.com/trustchile/movil-libs/lat_trust_mobile_ios_sso_library_podspec'

target 'AppName': do
use_frameworks!
...

# pod name and version to install
pod 'TrustSSO', '~> 1.5.8'

...
end
  1. Finally install previously specified dependencies using:
pod install

Associated Domains

In order to support FIDO2 features, host application needs to in support Associated Domains for sharing web credentials.

image

The following JSON code represents the contents of a simple association file. ie. https://< fully qualified domain >/.well-known/apple-app-site-association

{
"webcredentials": {
"apps": [
"ABCDE12345.com.example.app"
]
},
}

The above string is composed by the Apple developer TeamID (ABCDE12345) followed by the ApplicationBundleID (com.example.app).


Initialize

Use set(currentEnvironment: Environment) method to set the library's current environment (.prod or .test)

TrustSSOConfig.set(currentEnvironment: .test)
TrustSSOConfig.set(currentEnvironment: .prod)

Trust Transaction

Methods

Use shared instance to access TrustTransaction public methods. For example: Update an existing transaction receiving it's UUID as parameter

  • active: Bool value to be set on the respective transaction
  • completed: Bool value to be set on the respective transaction
  • authorizationMethod: String value that describes the auth method to be used
  • result: ResultHandler for success of failure cases
TrustTransaction.shared.updateTransaction(
transactionUuid: "12345",
authorizationMethod: "sms",
complete: true,
active: false,
) {
switch $0 {
case .success(let transaction):
// Do something with resulting transaction
case .failure(let error):
// Do something with resulting error
}
}

Fetch exsiting transactions for a specific user

  • userId: String value used for search transactions
  • result: ResultHandler for success of failure cases
TrustTransaction.shared.fetchTransactionsByUser(userId: "7304") {
switch $0 {
case .success(let transactions):
// Do something with resulting transaction
case .failure(let error):
// Do something with resulting error
}
}

Fetch exsiting transactions for a specific company

  • companyId: String value used for search transactions
  • result: closure that handles success of failure cases
TrustTransaction.shared.fetchTransactionsByCompany(companyId: "9512") {
switch $0 {
case .success(let transactions):
// Do something with resulting transactions array
case .failure(let error):
// Do something with resulting error
}
}

Trust Validation

Methods

Validate code using transactionUuid and otp value

  • transactionUuid: String needed for locating specific transaction
  • otp: Int value representing otp Int
  • result: ResultHandler for success of failure cases
TrustValidation.shared.validateCode(transactionUuid: "142", otp: 1) {
switch $0 {
case .success(let transaction):
// Do something with resulting transaction
case .failure(let error):
// Do something with resulting error
}
}

Validate QR code

  • code: String value representing code to validate
  • userId: String value representing user id
TrustValidation.shared.validateQrCode(code: "142", userId: "1") {
switch $0 {
case .success(let transaction):
// Do something with resulting transaction
case .failure(let error):
// Do something with resulting error
}
}

Trust FIDO2

Use set(authenticationAnchor: UIWindow) method for configuring the view where the authentication request will be displayed.

TrustFIDO2.shared.set(authenticationAnchor: window)

Methods

Register new user credentials

  • companyId: String valkue representing companyId
  • userId: String representing userId
TrustFIDO2.shared.registerRequest(userId: "7304", companyId: "9512") {
switch $0 {
case .success(let registerResultData):
// Do something with resulting data object
case .failure(let error):
// Do something with resulting error
}
}

Authenticate user credentials

  • userId: String value representing userId value
  • companyId: String value representing companyId value
TrustFIDO2.shared.signInRequest(userId: "7304", companyId: "9512") {
switch $0 {
case .success(let verificationResultData):
// Do something with resulting data object
case .failure(let error):
// Do something with resulting error
}
}

Trust IDP

Methods

Request authorization from client application user presenting a login form and then calling back to the client application

let trustIDP = TrustIDP.builder
.scheme("https://")
.baseURL("api.example.com")
.authPath("/example/path")
.scopes("example_scope")
.state("123456")
.resopnseType("example_type")
.acrValues("example_values")
.redirectURI("com.example.bundle//main")
.clientId("example_client_id")
.clientSecret("example_client_secret")
.grantType("authorization_code")
.build()

trustIDP?.requestAuthorization()

Ask for an AccessToken using a code provided in RequestAuthorization method

  • code: String value stored in application used to get AccessToken
  • result: ResultHandler for success of failure cases
TrustIDP.shared.tokenExchange(using: "idoj290pl21")

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

let trustNative = TrustNative.builder
.clientSecret(<YOUR_CLIENT_SECRET>)
.scope(<YOUR_SCOPES>)
.clientId(<YOUR_CLIENT_ID>)
.build()

Methods

PerformLogin

trustNative.performLogin() {
switch $0 {
case .success(let formResponse):
// Do something with resulting form response
case .failure(let error):
// Do something with resulting error
}
}

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 login

trustNative.sendForm(email: "example@email.com", password: "examplepassword") {
switch $0 {
case .success(let formStepResponse):
// Do something with resulting form step object
case .failure(let error):
// Do something with resulting error
}
}

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 code

trustNative.sendForm(a2f: "2k43") {
switch $0 {
case .success(let formStepResponse):
// Do something with resulting form step object
case .failure(let error):
// Do something with resulting error
}
}

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
}
}

Get Token

trustNative.getAccessToken() {
switch $0 {
case .success(let accessToken):
// Do something with resulting access token
case .failure(let error):
// Do something with resulting error
}
}

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
}

Errors

TrustError definition:

  • code: String value code of error check specification
  • localizedDescription: Error description as String

Codes

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