Wultra Mobile Token SDK for Android
Introduction
With Wultra Mobile Token (WMT) SDK, you can integrate an out-of-band operation approval into an existing mobile app, instead of using a standalone mobile token application. WMT is built on top of PowerAuth Mobile SDK. It communicates with the “Mobile Token REST API” and “Mobile Push Registration API.” Individual endpoints are described in the PowerAuth Webflow documentation.
To understand the Wultra Mobile Token SDK purpose on a business level better, you can visit our own Mobile Token application. We use Wultra Mobile Token SDK in our mobile token application as well.
Wultra Mobile Token SDK library does precisely this:
- Registers an existing PowerAuth activation to receive push notifications.
- Retrieves the list of operations that are pending for approval for a given user.
- Approves or rejects operations with PowerAuth transaction signing.
Note: We also provide an iOS version of this library
Installation
Requirements
minSdkVersion 16
(Android 4.1 Jelly Bean)- PowerAuth Mobile SDK needs to be available in your project.
Gradle
To use WMT in your Android app, add this dependency:
implementation "com.wultra.android.mtokensdk:wultra-mtoken-sdk:1.0.0"
Note that this documentation is using version 1.0.0
as an example. You can find the latest version at github’s release page.
Also, make sure you have mavenLocal()
repository among the project repositories and the version you are linking available in your local Maven repository.
Usage
To use this library, you need to have a PowerAuthSDK
object available and initialized with a valid activation. Without a valid PowerAuth activation, all endpoints will return an error. PowerAuth SDK implements two categories of services:
- Operations - Responsible for fetching the operation list (login request, payment, etc.), and for approving or rejecting operations.
- Push Messages - Responsible for registering the device for the push notifications.
Operations
This part of the SDK communicates with Mobile Token API endpoints.
Factory Extension With SSL Validation Strategy
Convenience factory method that will return a new instance. A new OkHttpClient
will be created based on chosen SSLValidationStrategy
in the last parameter.
fun PowerAuthSDK.createOperationsService(appContext: Context, baseURL: String, strategy: SSLValidationStrategy): IOperationsService
appContext
- application contextbaseURL
- address, where your operations server can be reachedstrategy
- strategy used when validating HTTPS requests. Following strategies can be used:SSLValidationStrategy.default
SSLValidationStrategy.noValidation
SSLValidationStrategy.sslPinning
Factory Extension With OkHttpClient
Convenience factory method that will return a new instance with provided OkHttpClient
that you can configure on your own.
fun PowerAuthSDK.createOperationsService(appContext: Context, baseURL: String, httpClient: OkHttpClient): IOperationsService
appContext
- application contextbaseURL
- address, where your operations server can be reachedhttpClient
-OkHttpClient
instance used for API requests
Retrieve the Pending Operations
To fetch the list with pending operations, implement the IOperationsService
API, you can call:
operationsService.getOperations(object : IGetOperationListener {
override fun onSuccess(operations: List<Operation>) {
// render operations
}
override fun onError(error: ApiError) {
// render error state
}
})
After you retrieve the pending operations, you can render them in the UI, for example, as a list of items with a detail of operation shown after a tap.
Start Periodic Polling
Mobile token API is highly asynchronous - to simplify the work for you, we added a convenience operation list polling feature:
// fetch new operations every 7 seconds periodically
if (!operationsService.isPollingOperations()) {
operationsService.startPollingOperations(7_000)
}
Approve or Reject Operation
Approve or reject a given operation, simply hook these actions to the approve or reject buttons:
// Approve operation with password
fun approve(operation: Operation, password: String) {
val auth = PowerAuthAuthentication()
auth.usePossession = true
auth.usePassword = password
auth.useBiometry = null // needed only when approving with biometry
operationsService.authorizeOperation(operation, authentication, object : IAcceptOperationListener {
override fun onSuccess() {
// show success UI
}
override fun onError(error: ApiError) {
// show error UI
}
})
}
// Reject operation with some reason
fun reject(operation: Operation, reason: RejectionReason) {
operationsService.rejectOperation(operation, reason, object : IRejectOperationListener {
override fun onSuccess() {
// show success UI
}
override fun onError(error: ApiError) {
// show error UI
}
})
}
Off-line Authorization
In case the user is not online, you can use off-line authorizations. In this operation mode, the user needs to scan a QR code, enter PIN code or use biometry, and rewrite the resulting code. Wultra provides a special format for the operation QR codes, that are automatically processed with the SDK.
To process the operation QR code, you can use:
@Throws(IllegalArgumentException::class)
fun onQROperationScanned(scannedCode: String): QROperation {
// retrieve parsed operation
val operation = QROperationParser.parse(payload)
// verify the signature against the powerauth instance
val verified = powerAuthSDK.verifyServerSignedData(operation.signedData, operation.signature.signature, operation.signature.isMaster())
if (!verified) {
throw IllegalArgumentException("Invalid offline operation")
}
return operation
}
After that, you can produce an off-line signature using the following code:
@Throws
fun approveQROperation(operation: QROperation, password: String): String {
val authentication = PowerAuthAuthentication()
authentication.usePossession = true
authentication.usePassword = password
return operationsService.authorizeOfflineOperation(operation, authentication)
}
Operations API Reference
All available methods and attributes of IOperationsService
API are:
listener
- Listener object that receives info about operation loading.acceptLanguage
- Language settings, that will be sent along with each request. The server will return properly localized content based on this value.getLastOperationsResult()
- Cached last operations result.isLoadingOperations()
- Indicates if the service is loading operations.getOperations(listener: IGetOperationListener?)
- Retrieves pending operations from the server.listener
- Called when operation finishes.
isPollingOperations()
- If the app is periodically polling for the operations from the server.startPollingOperations(pollingInterval: Long)
- Starts periodic operation polling.pollingInterval
- How often should operations be refreshed.
stopPollingOperations()
- Stops periodic operation polling.authorizeOperation(operation: Operation, authentication: PowerAuthAuthentication, listener: IAcceptOperationListener)
- Authorize provided operation.operation
- Operation to approve, retrieved fromgetOperations
call.authentication
- PowerAuth authentication object for operation signing.listener
- Called when authorization request finishes.
rejectOperation(operation: Operation, reason: RejectionReason, listener: IRejectOperationListener)
- Reject provided operation.operation
- Operation to reject, retrieved fromgetOperations
call.reason
- Rejection reason.listener
- Called when rejection request finishes.
fun authorizeOfflineOperation(operation: QROperation, authentication: PowerAuthAuthentication)
- Sign offline (QR) operationoperation
- Offline operation retrieved viaQROperationParser.parse
method.authentication
- PowerAuth authentication object for operation signing.
signOfflineOperationWithBiometry(biometry: ByteArray, offlineOperation: QROperation)
- Sign offline (QR) operation with biometry data.biometry
- Biometry data retrieved frompowerAuthSDK.authenticateUsingBiometry
call.offlineOperation
- Offline operation retrieved viaprocessOfflineQrPayload
method.
For more details on the API, visit IOperationsService
code documentation.
Push Messages
This part of the SDK communicates with Mobile Push Registration API.
To register PowerAuth enabled application to receive push notifications, use one of the following convenience extension methods (Kotlin):
Extension Factory With SSL Validation Strategy
This factory method will create its own OkHttpClient
instance based on the chosen SSL validation strategy.
fun PowerAuthSDK.createPushService(appContext: Context, baseURL: String, strategy: SSLValidationStrategy): IPushService
appContext
- application contextbaseURL
- address, where your operations server can be reachedstrategy
- strategy used when validating HTTPS requests. Following strategies can be used:SSLValidationStrategy.default
SSLValidationStrategy.noValidation
SSLValidationStrategy.sslPinning
Extension Factory With OkHttpClient
fun PowerAuthSDK.createPushService(appContext: Context, baseURL: String, httpClient: OkHttpClient): IPushService
appContext
- application contextbaseURL
- address, where your operations server can be reachedhttpClient
-OkHttpClient
instance used for API requests
Registering to Push Notifications
To register an app to push notifications, you can simply call the register method:
// first, retrieve FireBase token
FirebaseInstanceId.getInstance().instanceId.addOnCompleteListener { task ->
if (task.isSuccessful) {
task.result?.token?.let { token ->
pushService.register(token, object : IPushRegisterListener {
override fun onSuccess() {
// push notification registered
}
override fun onFailure(e: ApiError) {
// push notification failed
}
})
}
} else {
// on error
}
}
Push Message API Reference
All available methods of the IPushService
API are:
acceptLanguage
- Language settings, that will be sent along with each request.register(fcmToken: String, listener: IPushRegisterListener)
- Registers Firebase Cloud Messaging token on the backendfcmToken
- Firebase Cloud Messaging token.listener
- Called request finishes
For more details on the API, visit IPushService
code documentation.
Error Handling
All methods that communicate with server APIs return an ApiError
instance in case of an error.
Every API error contains an original exception that was thrown, and a convenience error property for known API error states (for example, if the operation is already canceled during approval).
License
All sources are licensed using the Apache 2.0 license. You can use them with no restrictions. If you are using this library, please let us know. We will be happy to share and promote your project.
Contact
If you need any assistance, do not hesitate to drop us a line at [email protected] or our official gitter.im/wultra channel.
Security Disclosure
If you believe you have identified a security vulnerability with Wultra Mobile Token SDK, you should report it as soon as possible via email to [email protected]. Please do not post it to the public issue tracker.