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:
- Initialize cocoapods in your project (if it's not already done):
pod init
this would generate a Podfile and Pods folder.
- 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
- 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.
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
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
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
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 |