/images/resources/code-examples/code-examples-kotlin-haapi.jpg

Kotlin Android App using HAAPI

On this page

This tutorial shows how to run a code example that implements mobile OpenID Connect in a Kotlin App using the Hypermedia Authentication API (HAAPI). See also the API Driven Demo Client tutorial for an introductory guide that runs a simple web client.

Overview

The code sample provides a basic Android implementation to demonstrate how to integrate a HAAPI-driven authentication flow in an app. It uses the HAAPI UI SDK, a high-level SDK that handles the whole flow, requiring just minimal configuration and customization. The app initially presents a view to start the authentication process:

Android Initial View

The authentication workflow is then managed as a series of fast API requests that return JSON responses. The SDK processes each API response to perform various actions including rendering of forms:

Android Login Form

Once authentication completes, the app presents its Authenticated View, to simulate a mobile app that works with access tokens to call APIs. The app can then easily perform other OAuth operations such as refreshing tokens and ending the authenticated session:

Android Authenticated View

From this point onwards the app will operate like a traditional mobile OAuth client and call APIs.

Get the Code

First, ensure that you are running an up-to-date version of Android Studio, then clone the GitHub repository and open its folder to view the Kotlin classes used.

Quick Start

The easiest way to run the code example is to point it to a deployed and preconfigured instance of the Curity Identity Server, running in Docker. This is done via a script included with the example that is explained in the Mobile Setup how-to:

bash
1
./start-idsvr.sh

The result is a working instance of the Curity Identity Server, listening on the Android emulator's default host IP (https://10.0.2.2:8443), ready for the mobile app to connect to. The Admin UI is also available and can be accessed using the following details:

PropertyValue
URLhttps://localhost:6749/admin
Useradmin
PasswordPassword1

The deployed system also includes a user account of demouser / Password1 that can be used to sign in.

Deploying the Curity Identity Server with a Remote URL

It will sometimes be necessary to access the instance of the Curity Identity Server remotely. E.g., when you want to test the mobile app from a physical device, without a debug connection with Android Studio. You can use the ngrok tool to quickly expose local applications on the Internet. You can edit the start-idsvr.sh and stop-idsvr.sh files to use ngrok (set USE_NGROK=true). This will result in exposing the containerized instance of the Curity Identity Server under a random domain similar to https://87ce095409f9.ngrok.io. Should you use this option you will have to update the apps' configuration (see Updating the App Configuration).

If you want more control over exposing the Curity Identity Server with ngrok, then have a look at the Exposing with ngrok tutorial.

Configuration

The code example uses the following client settings, including the haapi and code capabilities. Further details on HAAPI specific settings are explained in the Android HAAPI SDK tutorial.

xml
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
<config xmlns="http://tail-f.com/ns/config/1.0">
<profiles xmlns="https://curity.se/ns/conf/base">
<profile>
<id>token-service</id>
<type xmlns:as="https://curity.se/ns/conf/profile/oauth">as:oauth-service</type>
<settings>
<authorization-server xmlns="https://curity.se/ns/conf/profile/oauth">
<client-store>
<config-backed>
<client>
<id>haapi-android-client</id>
<client-name>Haapi Android Client</client-name>
<no-authentication>true</no-authentication>
<redirect-uris>app://haapi</redirect-uris>
<proof-key>
<require-proof-key>false</require-proof-key>
</proof-key>
<refresh-token-ttl>3600</refresh-token-ttl>
<scope>address</scope>
<scope>email</scope>
<scope>openid</scope>
<scope>phone</scope>
<scope>profile</scope>
<user-authentication>
<allowed-authenticators>Username-Password</allowed-authenticators>
</user-authentication>
<capabilities>
<code>
</code>
<haapi>
</haapi>
</capabilities>
<validate-port-on-loopback-interfaces>true</validate-port-on-loopback-interfaces>
<attestation>
<disable-attestation-validation>true</disable-attestation-validation>
<android>
<package-name>io.curity.haapidemo</package-name>
<signature-digest>Z2DKEZO2XWFWQnApoRCzhqhIxzODe7BUsArj4Up9oKQ=</signature-digest>
<signature-digest>QqGGZJ4Kzv75J1MyPtG2WA59Z1ezNIshN1o1Ayh7qU4=</signature-digest>
<android-policy>android-dev-policy</android-policy>
</android>
</attestation>
</client>
</config-backed>
</client-store>
</authorization-server>
</settings>
</profile>
</profiles>
</config>

Updating the App Configuration

The demo app's configuration settings are specified in the Configuration class. If using the quick start, use the default values.

If you deployed the Curity Identity Server with ngrok, or have your own configuration, then you need to provide the details to the app configuration. Update the newInstance method in the Configuration class to return proper values:

kotlin
1234567891011
fun newInstance(): Configuration =
Configuration(
clientId = "haapi-android-client",
baseURLString = "https://idsvr.example.com",
tokenEndpointPath = "/token",
authorizationEndpointPath = "/authorize",
userInfoEndpointPath = "/userinfo",
redirectURI = "app://haapi",
scope = listOf("openid", "profile", "address"),
useSSL = true
)

Run the App

Once the above configuration is complete, run the app and use whichever authenticators and users are configured in the Curity Identity Server. If using the quickstart option, the username-password authenticator is already configured, and the following username and password can be used to log in: demouser / Password1.

HAAPI Integration

Integration with the HAAPI UI SDK is described in detail in the HAAPI guide and can be summarized in these steps that the app implements:

  1. In the app/build.gradle file, the SDK is defined as a dependency.
  2. The DemoApplication class implements an interface from the SDK and creates a configuration object that is then used by the SDK itself.
  3. The AndroidManifest.xml file has a declaration of the HAAPIFlowActivity — an activity provided by the SDK.
  4. The MainActivity class is responsible for starting the HAAPI activity. When the authentication is complete, the obtained tokens are returned to the MainActivity. These are then passed to another activity, that is responsible for displaying them.

Using and Refreshing Access Tokens

Once the client obtains an access token it will use it to call APIs in the standard way, by sending them as bearer tokens in the HTTP Authorization header. When the access token expires, the refreshAccessToken method of the HaapiFlowViewModel class is used to get a new set of tokens. Have a look at the TokensViewModel and TokensFragment classes (in the TokensFragment.kt file) to see how to obtain the view model and use it to refresh tokens.

Logout

Logout can be implemented in a simple manner, by just removing tokens from the app and redirecting back to the MainActivity (unauthenticated view). Have a look at the TokensViewModel class (in the TokensFragment.kt file) to see how to perform logout.

Customizing the Look and Feel

The UI SDK allows for a simple change of the styles used by the view components. Have a look at the res/values/styles.xml and res/values/colors.xml files to see the techniques used in the demo app to change the default theme. Note that the custom theme is applied to the HAAPIFlowActivity in the AndroidManifest.xml file. Have a look at the customization tutorial to learn more about changing the look and feel of your authentication flow.

Non-Compliant Devices

The HAAPI SDK uses hardware-backed attestation features to perform secure client authentication. Some older Android devices may not support the recommended method for client attestation. In these cases use a fallback method of proving the client identity before authentication. Have a look at the Implementing HAAPI Fallback tutorial to learn how to configure this.

Conclusion

The Hypermedia Authentication API provides a number of benefits to mobile apps, in terms of both financial grade security and login usability:

  • The app gets an improved login user experience.
    • The Curity Identity Server continues to dictate security.
  • The authentication workflow can be updated without needing to redeploy the app.
  • Only genuine mobile clients can attempt user authentication.
  • Man In the Browser (MITB) risks are eliminated for most authentication methods.