App2App Logins via Hypermedia Authentication API
The App2App Mobile Architecture article describes how App2App can be used to implement Strong Customer Authentication (SCA). It also discusses how to use App2App in an Open Banking setup with multiple merchants and banks.
This tutorial will demonstrate how to run a basic App2App solution using a mobile code sample, the Curity Identity Server, and an external mobile app.
You can use the BankID App to sign in the user in with strong authentication, via the BankID public test environment:
In real-world usage, the BankID app would be integrated into a bank's PSD2 and Open Banking solutions. Merchant apps could then integrate with the bank solution, allowing consumers to sign in to merchant apps with BankID to access their bank account information securely.
The components that enable this are illustrated below. The mobile app calls the Curity Identity Server, which in turn makes API calls over Mutual TLS to BankID's back end.
The client app retrieves the login result by polling the Curity Identity Server, which will issue an authorization code once BankID indicates a successful login.
To get up and running with a developer test account, visit the BankID Developer Page and follow the below steps.
|Get an Account||Follow the instructions in the 'How to get a test BankID' document|
|Android App Download||Download the test APK file from the developer page|
|iOS App Download||Download BankID from the App Store and set the server to 'cavainternal.test.bankid.com' in configuration settings|
Once this is complete, test a sign-in from the website at https://demo.bankid.com using either a desktop browser or a mobile browser.
- From a desktop browser, select the second option and perform a Web2App login on your mobile device.
- From a mobile browser, select the first option and perform an App2App login when prompted.
In both cases, it is then necessary to enter your mobile security code on the device, after which the browser client will receive the authentication result by polling BankID APIs.
The connection from the Curity Identity Server to the BankID API uses a financial-grade Mutual TLS connection. To enable Mutual TLS, the system utilizes the following Public Key Infrastructure (PKI) resources:
|BankID Test Client Certificate + Private Key||A client-side credential used for the Mutual TLS connection|
|BankID Test Issuer Root Certificate||The public key of the root certificate authority for testing|
The first of these can be downloaded from the developer page. Both its private key password and the root certificate are provided in section 8 of the BankID Relying Party Guidelines document.
Next, in the Curity Identity Server, add the issuer root certificate to the trust store and the client key to the client key store:
In the Admin UI, you can configure an HTTP Client that connects to the BankID Test Environment using Mutual TLS. Select the client keystore, and also select the 'Use Trust Store' option so that the issuer certificate is trusted:
Next, add a BankID authenticator and select the HTTP Client you configured. Ensure that the OAuth client uses 'mode=test' for the BankID test environment.
Curity's HAAPI Android Code Sample demonstrates an implementation of the Hypermedia Authentication API in a demo app. This is used in this tutorial to demonstrate App2App login.
BankID is not supported for emulators, so you will need to run the sample on a real device. This tutorial will use Android, where there are fewer prerequisites for running demo apps on devices, though equivalent steps could be followed for iOS.
In the below screenshot, an OAuth client with a name that matches the code sample has been created, with the following three capabilities, as needed for HAAPI logins. See the Android HAAPI SDK article for full details on configuration.
The Curity Identity Server ensures that no malicious app can spoof a genuine HAAPI mobile client and attempt authentication. This is done using a technique called Client Attestation, which requires some additional settings:
To run the sample on a mobile device, begin by clicking an initial login button to send a standard OpenID Connect authorization redirect message.
Next, you will be presented with a list of authenticators configured for the mobile client. This screen can be bypassed if the client has only one authenticator or if an authenticator is selected at runtime by the client. This can be accomplished by sending the OpenID Connect claims parameter with an 'acr' value:
Next, select the BankID authenticator, then choose the BankID option to deep-link to the BankID app on the same device. If required, the client app could decide not to present this intermediate screen so that the deep link is immediate:
The user will then be switched to the BankID app and will enter their BankID Security Code. While this is taking place, the client app polls the Curity Identity Server. This mechanism keeps the user informed and enables any failure conditions to be handled gracefully:
Once sign-in completes successfully, The Curity Identity Server receives a success result from BankID and issues an authorization code. The app then swaps the code for a set of tokens, then call its own APIs:
The sample app allows itself to be driven by Hypermedia API JSON responses, which contain instructions for the client to follow. A few examples are summarized below. These actions will be familiar to anyone who has worked with OAuth messages:
|Automatic Redirect||A hypermedia instruction to redirect to a URL with parameters|
|External Links||Invoking a deep link or opening a system browser when this is the more secure option|
|Form Display||Data containing form elements to render and a POST URL for submitting edits such as entered credentials|
|Receiving Results||Receiving the final authorization code at the end of the workflow, or an error result|
data class BankIdClientOperationStep internal constructor( val activationLink: Link?, override val actionModel: ClientOperationActionModel.BankId, override val metadata: Metadata?, override val type: RepresentationType, override val actions: List<Action>, override val links: List<Link>, override val messages: List<UserMessage> ) : HaapiRepresentation, ClientOperationStep
A key benefit of hypermedia-driven workflows is that they are very easy to update dynamically. This is usually more straightforward to manage than releasing a new app version, then waiting for users to upgrade.
The below video provides step-by-step instructions on getting App2App logins working using BankID. This includes the BankID setup and the Curity Identity Server configuration.
At Curity, we are continuing to improve our HAAPI SDKs to make it as easy as possible to integrate into apps. Our samples provide classes that reliably handle all types of responses for Web, iOS, and Android. We also offer default presentations for UI elements, which can be customized as required.
HAAPI flows have some security improvements over standard OAuth redirects, as explained in our Hypermedia Authentication API Whitepaper. We are working with the Financial Grade API (FAPI) Working Group and other parties to establish HAAPI and its security features as a standard.
The Curity Identity Server has proven support for App2App authentication to enable the integration of 'out of the box' Strong Customer Authentication solutions. We frequently extend our Authentication Service to support additional providers.
Using the Hypermedia Authentication API provides customers with a high-quality solution at a low cost. The result is more secure apps, a better login user experience, and an overall easier implementation.