//HAAPI Android UI.Widget Documentation

HAAPI Android UI.Widget Documentation

[androidJvm] An Android library with classes and layout definitions that are used to perform an Haapi Flow authorization with Curity Identity ServerHypermedia Authentication API (HAAPI) from Android devices.

The library allows a client to implement an authorization flow via HAAPI by using a set of prebuilt UI screens that represent the different responses/steps that may be involved in the API-driven flow.

Requirements

We highly recommend you keep HAAPI UI.Widget up-to-date.

⚠️ The HAAPI UI.Widget is not tested on Jetpack Compose.

Getting started

Setting up HAAPI UI.Widget

To install the SDK, add identityserver.haapi.android.ui.widget to the dependencies block of your app/build.gradle file:

apply plugin: 'com.android.application'

android { ... }

dependencies {
    implementation("se.curity.identityserver:identityserver.haapi.android.ui.widget:4.1.0")
    ...
}

Pairing the application with the client on the Curity Identity Server

Get the package name of your application and the API signature of your application.

To get the API signature of your application, run this command in the terminal at the project level:

./gradlew SigningReport

It should produce this result:

> Task :app:signingReport
Variant: debug
Config: debug
...
SHA-256: AC:8A:65:9D:EC:3B:E1:FD:FC:A0:28:87:FA:AB:E0:E0:A5:04:BE:15:7A:2C:05:CB:86:47:FE:9B:E5:7B:D4:1F
Valid until: Wednesday, 7 June 2051
...

Update the client that is the Oauth client with the HAAPI capability using the Android attestation on your Curity Identity Server by adding the following information:

Package Name ->com.example.myhaapiui (ℹ️ This is an example. Use your own package name.)

Signature Digest ->AC:8A:65:9D:EC:3B:E1:FD:FC:A0:28:87:FA:AB:E0:E0:A5:04:BE:15:7A:2C:05:CB:86:47:FE:9B:E5:7B:D4:1F (ℹ️ This is an example. Use your own API signature.)

Setting up Digital Asset Links

Associate your app and domain by configuring the Digital Asset Link association in your app Manifest.xml file by adding an entry like below.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="my.app.package">
    ...
    <application
        ...
        android:name="TestApplication">
        <meta-data android:name="asset_statements" android:resource="@string/asset_statements"/>
        ...
    </application>
</manifest>

Next, it is necessary to define the string resource entry referenced in the manifest like the following.

<resources>
    <string name="app_name">My App</string>

    <!-- Digital Asset Links app association -->
    <string name="asset_statements" translatable="false">[{\"include\": \"https://10.0.2.2:8443/.well-known/assetlinks.json\"}]</string>
</resources>

WebAuthn and Passkeys

When the app needs to trigger a WebAuthn Authorization interaction flow, it can do so by either delegating responsibility on the OS by opening a browser or by using an integrated native flow inside the app. The default behaviour has changed and now uses the native integrated WebAuthn support. The configuration has been removed and now the use of the browser is relegated to an alternate fallback action in case the native support fails.

Native WebAuthn support is currently experimental. Use with caution. Provide any relevant feedback about its usage and also if/when finding bugs to help us improve the user and developer experience.

Native WebAuthn support is provided by:

⚠️ Cross-platform Security-Keys with user verification are currently not supported.

Native WebAuthn support for Android is available in Curity Identity Server starting from version 8.7.0.

To use passkeys on Android, you need to meet certain requirements. Passkeys are supported on devices running Android 9 (Pie) or later. Here are the key requirements and details:

Discoverable Credentials support for Android is available in Curity Identity Server starting from version 9.3.0.

Integration

Integrating with the IdsvrHaapi UI framework to run a Haapi Flow requires minimal code and setup to get your application up and running. This is by design and intended to provide a low code out-of-the-box experience that enables client applications to take advantage of the security features provided by a HyperMedia Authentication API. Configuring the framework is achieved by implementing the HaapiUIWidgetApplication which provides the setup that drives the UI behaviour and whose main configuration property is WidgetConfiguration. For more advanced use cases, some degree of UI customization is also available and can be applied by making use of Theming capabilities from the Android styles and themes.

Start the HAAPI flow

When launching the HaapiFlowActivity, the HAAPI flow starts, then is driven by the API and finally returns an OauthModel.Token which contains an OAuth Access Token. The OauthModel.Token has to be stored and managed in your application.

OAuth Token lifecycle management

Oauth.Token models follow the specification for OAuth 2.0 tokens, which means their lifecycle can be managed to refresh their validity or revoke and make them invalid/unusable. Haapi UI framework provides a set of APIs that make it possible to manage the lifecycle of held tokens.

DCR configuration for Android devices that do not support Key Attestation

The HAAPI UI.Widget security features require that Android devices support hardware-backed Key Attestation. Unfortunately, the Android system suffers from ecosystem fragmentation due to the many existing brands/manufacturers, and as such, many of them don't support the security requirements. For those devices, users will not be able to start the HAAPI flow unless the WidgetConfiguration has a DCR configuration in place. In this case, devices that do not have valid Key Attestation support can automatically fallback to the DCR configuration and continue using Haapi in a secure way.

To configure it, please perform the following steps:

  1. In your Curity Identity Server, create and configure a client that supports one of the following authentication methods:
    1. Secret
    2. Mutual TLS
    3. Signed JWT
  2. In your Curity Identity Server, create and configure a DCR template client ID, and add the client that was created in point 1 to the Dynamic Client Registration section.
  3. In your Curity Identify Server, find (or configure) the DCR client registration endpoint (oauth-dev-dynamic-client-registration) and take note as it will be required in the next point.
  4. In your application, update your WidgetConfiguration by setting the Client Authentication method and the DCR configuration as the example demonstrates below:
class ClientApplication : Application(), HaapiUIWidgetApplication {
  private val baseUri = URI.create("https://10.0.2.2:8443")

  override val widgetConfiguration: WidgetConfiguration
    get() = WidgetConfiguration.Builder(
      clientId = "my-client-id", // It is the client id that is used and was updated above.
      baseUri = baseUri,
      tokenEndpointUri = baseUri.resolve("/token-endpoint"),
      authorizationEndpointUri = baseUri.resolve("/authorization-endpoint"),
      appRedirect = "app://haapi"
    )
  	.setClientAuthenticationMethod(
      WidgetConfiguration.ClientAuthenticationMethod.Secret("my-secret")
    )
    .setDcr(
      WidgetConfiguration.Dcr(
        templateClientId = "dcr-template-client-haapi-android",
        clientRegistrationEndpointUri = baseUri.resolve("/oauth-registration"),
        context = this
      )
    )
  	.build()
}

Configuring HTTPCookie management

To establish and maintain a potentially long-lived session between client and server, HttpURLConnection includes an extensible cookie manager. For more information on setting up cookie management for HttpUrlConnection please refer to Android API docs. The HAAPI UI.Widget framework does not handle this automatically as it should be setup at the application level as per use case requirement. To do so, only a couple of lines of code are required to enable the cookie management behaviour like demonstrated below.

// override default behaviour to accept all cookies
CookieHandler.setDefault(CookieManager(null, CookiePolicy.ACCEPT_ALL))

// keep default behaviour to accept only cookies from original server
val cookieManager = CookieManager()
CookieHandler.setDefault(cookieManager)

Guide

Additional features

References

HaapiLogger

When using the HAAPI UI.Widget it is possible to get information about what is happening during the Haapi Flow by analyzing the framework logs. This kind of information is intended to help assess issues and troubleshoot the framework behavior and to allow the client developer to gather and provide the necessary data when support is needed. This logging mechanism is built on top of the System Logging in the Android Runtime, more specifically making use of android.util.Log.

Additional note

If more control over transport/serialization or custom behavior is needed, the HAAPI Android Driver and HAAPI Android SDK can be used as they define lower-level building blocks to issue HAAPI requests.

Packages

Name
se.curity.identityserver.haapi.android.ui.widget
se.curity.identityserver.haapi.android.ui.widget.internal.models
se.curity.identityserver.haapi.android.ui.widget.layouts
se.curity.identityserver.haapi.android.ui.widget.models