API-Driven UI#
By default, the Curity Identity Server provides a user interface mostly based on server-side rendering using the Velocity template system. However, it’s also possible to use the Hypermedia Authentication API to create an API-driven (or HAAPI-driven UI) user interface, namely a single page application (SPA).
When the API-driven UI is enabled, the server renders a well-known loader/bootstrap template (views/api-driven-ui/index.vm) in the first interactive step of the authentication flow, which initializes the API-driven application.
The exact moment depends on configuration and user session state (e.g. it can be the authenticator selector, a specific authenticator, the user consent page, etc.).
The application is then responsible for using HAAPI to drive the authentication flow, taking full control of the user interface.
The API-driven UI application is effectively part of the Curity Identity Server (i.e. it runs in the server origin) and the details to access HAAPI are all resolved by the server and provided on bootstrap. Namely, a built-in HAAPI client is used, which doesn’t require any additional configuration.
API-driven UIs can only be used for OAuth-initiated flows.
The API-driven UI can be enabled at different levels by setting the UI Experience setting to API-driven UI:
- Globally
-
Admin UI → System → General
- Configuration: environment settings
-
- For an authentication profile, affecting also the linked token profiles
-
Admin UI → Profiles → Authentication → General
- Configuration: authentication profile settings
-
- For specific configuration-based OAuth clients
-
Admin UI → Profiles → Token → Clients → User Authentication
- Configuration: OAuth client settings
-
By default, more specific configurations inherit from the parent. For example, if the API-driven UI is enabled globally, it will be enabled for all authentication profiles (and OAuth clients on linked token profiles), unless they are specifically configured to use a different UI experience. In addition, if a certain authentication profile is configured to use the API-driven UI, all OAuth clients of linked token profiles will also inherit this setting.
Currently, API-driven UIs can only be enabled for configuration-based OAuth clients.
Built-in React UI#
The Curity Identity Server ships with an API-driven UI built using React - the HAAPI React App - which is part of the public UI Kit. The application supports all HAAPI features required to drive authentication flows and is able to cover different use cases out of the box, including HAAPI responses from custom plugins, as long as they follow the HAAPI guidelines. The application is organized as a set of React components that provide full management of HAAPI flows with minimal setup, allowing customization and extension at different levels. Check the documentation in the public repository for more details.
The following templates and assets are used to serve the HAAPI React App:
assets/css/api-driven-ui.cssandassets/js/api-driven-ui.jsfiles.- Output of the build process of the HAAPI React App, containing the application code and styles, renamed for convenience.
views/api-driven-ui/index.vmtemplate.- Loader template. Includes the aforementioned assets and theme-related assets, and defines other aspects like content security policy (CSP) directives.
fragments/api-driven-ui/theme.vmtemplate.- Outputs the part of the application bootstrap configuration related to themes (see the next section for details).
The look and feel of the HAAPI React App is customizable using the theming capabilities .
Building Custom UIs#
If the built-in theming capabilities are not sufficient for your use case, you can also bring your own custom API-driven UI application.
One possible approach is using the HAAPI React App as a base, customize/configure it as needed, then include the updated assets in your Curity Identity Server distribution.
Another approach is to create a completely new application, using your preferred technology stack, and adjust the loader template to serve it.
Note that it’s even possible to have multiple API-driven UIs, leveraging template organization features.
For example, a different loader template (views/api-driven-ui/index.vm) can be defined for different template areas.
Whatever approach is used, when the server renders the loader template, the following Velocity context variables are present (in addition to the ones available to all templates):
$_apiDrivenClientInfo- contains the information required to configure the HAAPI Web Driver.$_apiDrivenClientInfo.clientId- evaluates to the ID of the HAAPI client to use.$_apiDrivenClientInfo.tokenEndpoint- evaluates to the URI of the token endpoint to be used by the HAAPI client.
$_apiDrivenInitialUrl- evaluates to the URL that the application should use for the first HAAPI request (always a GET request).
Example of how to use the provided information to configure HAAPI Web Driver in an application:
// Using 'createHaapiFetch' from the '@curity/identityserver-haapi-web-driver' package
const fetchConfig = {
clientId: '$_apiDrivenClientInfo.clientId',
tokenEndpoint: '$_apiDrivenClientInfo.tokenEndpoint',
};
const haapiFetch = createHaapiFetch(fetchConfig);
The HAAPI React App manages configuration of the HAAPI Web Driver based on the data provided via a bootstrap configuration object (see next section).
If you’re just using the HAAPI React SDK - i.e. the React building-blocks/components - the HAAPI Web Driver configuration can be supplied to the HaapiStepper component, which handles the actual integration with the driver:
<HaapiStepper config={{ bootstrap: { initialUrl: '...', haapi: fetchConfig } }}>
<HaapiStepperStepUI />
</HaapiStepper>
Configuration for the HAAPI React App#
The HAAPI React App expects a bootstrap configuration object to be present in the window object under the __CONFIG__ property.
The structure of this configuration object is shown below using a TypeScript interface definition:
interface Configuration {
/** As defined above for '$_apiDrivenInitialUrl'. */
initialUrl: string,
haapi: {
/** As defined above for '$_apiDrivenClientInfo.clientId'. */
clientId: string,
/** As defined above for '$_apiDrivenClientInfo.tokenEndpoint'. */
tokenEndpoint: string,
},
theme: {
/** Details about the logo. If not provided, a logo is not shown. */
logo?: {
/** Full path to the logo image. */
path: string,
/** As defined for the '$logo_inside' Velocity variable */
isInsideWell: boolean,
},
/** Details about the page symbols. If not provided, page symbols are not shown. */
pageSymbols?: {
/** Map of view/template name to symbol path. */
views?: Record<string, string>;
/** Map of plugin implementation type to symbol path. */
plugins?: Record<string, string>;
/** Path for the default page symbol. */
default: string;
}
}
}
The theme property of the configuration object is produced by the fragments/api-driven-ui/theme.vm template, which is included by the loader template.
This facilitates theme-related configuration, avoiding the need to modify the loader template.
Regarding page symbols, the HAAPI React App applies the following resolution logic:
- If
theme.pageSymbolsis not defined, page symbols are not shown. - If a symbol is defined in
theme.pageSymbols.viewsmatching theviewNamein the metadata of the current HAAPI step, use it. - If a symbol is defined in
theme.pageSymbols.pluginsmatching the type of the plugin inferred from the metadata of the current HAAPI step, use it. - If nothing else, use the symbol defined in
theme.pageSymbols.default.
Enabling in Older Versions (deprecated)#
This section describes an older mechanism to enable API-driven UIs when the server didn’t include a built-in one. This approach is now deprecated and only kept for backward compatibility.
Enable API-driven on the selected authentication profiles by adding the api-driven-ui configuration parameter in the corresponding authentication-service settings.
Assign the use_api_driven_ui template setting to true. This is done by adding #set ($use_api_driven_ui = true) to a settings.vm file:
- located on the
overridesfolder, if the API-driven UI should always be enabled. - located on a template area, if the API-driven UI should only be enabled for certain clients.
Create a index.vm velocity template with the HTML document to load the API-driven application. This file should be present inside an api-driven-ui directory, located on the overrides folder or on a template area. The $_apiDrivenClientInfo Velocity context object contains the information required to configure HAAPI Web Driver, as described in the previous sections.
The API-driven application will be loaded on the first interactive step of the authentication flow, which can be the authenticator selector or a specific authenticator user interface.