Hypermedia Authentication API demo client

Hypermedia Authentication API demo client

tutorials

The authentication API is currently in Beta

General Availability (GA) of the Curity Authentication API will come soon. This information will help you prepare.

What is the Authentication API

If you browsed the examples directory of the Curity Identity Server recently you may have stumbled upon a folder named api-driven. Inside, you’ll find resources about an authentication API exposed by the Identity Server. The API allows you to create authentication flows straight from your client, without the need of resorting to the browser, but still maintaining the same level of security which is granted by OAuth and OpenID Connect frameworks. What is more it is a hypermedia API, thus it enables a hypermedia-driven flow, where the server drives the client through the steps required to authenticate the user. These steps can be dynamic and do not require any modification on the client side when the server changes the authentication steps. As long as the client can understand the hypermedia representation of resources sent by the server, it can proceed with the flow.

Hypermedia Authentication API available from version 5.2.

If you can't find the api-driven directory inside of $INSTALL_DIR/examples check if you're using Curity Identity Server at least in the version 5.2.

Apart from the documentation, in the directory you’ll also find an example client that you can use to check the possibilities that the API offers. In this article we’ll show you how to run the demo application and how you can easily tailor the client to your needs.

Prerequisites

In order to run the demo application you need to make sure of a few things.

  1. Use Curity Identity Server at least in version 5.2. The Hypermedia Authentication API has been introduced in this version, so you won’t be able to follow this tutorial with an earlier version of the Identity Server.

  2. Configure the Identity Server at least with the example configuration. We assume in this tutorial that you run your instance of Curity Identity Server at localhost and the default port 8443. If not, you will have to adjust some settings where https://localhost:8443 is used to reflect the address that you actually use.

  3. The Authentication API is still in beta and is disabled by default. To enable support for the API, the server needs to be run with the system property se.curity.haapi.enable set to true. Follow this steps to set this property using CLI:

    • Start the command shell by running idsh command from the bin directory of your Curity Identity Server installation folder.

    • Enter configuration mode by running configure command.

    • Enter the following command. Use appropriate service role instead of default if your server runs in a different role. Also remember that this overwrites the configuration setting, so if you changed the JVM options before, adjust the value accordingly.

      set environments environment services service-role default jvm-options "-XX:+UseG1GC -Dse.curity.haapi.enable=true"
    • Enter commit command and exit the shell.

    • As we’ve changed the JVM settings you need to restart the Curity Identity Server.

    If you prefer to use the Admin UI or RESTCONF to change the JVM settings, have a look at the documentation.

  4. Prepare a client. Below are the requirements for some values the client should have set. You can change these values to anything you like, but you will then have to adjust those values in the demo application. Make sure that you have a client, which:

    • Has the name haapi-public-client.
    • Has at least the client credentials and code capabilities enabled. If you’re creating a new client select secret as the authentication method and set any password. We will change that in a moment.
    • Has a redirect URI registered: https://localhost:7777/client-callback.
    • Has an allowed origin registered: https://localhost:8443.
    • Has at least the read scope.
    • Has the Require Proof Key option disabled. This can be found in the Client Application Settings group, in the Advanced tab.
    • Has at least two Authentication methods enabled, so you’ll be able to see an authentication method selector.
  5. The client needs to have an additional capability enabled in order to use the API: authorization-api-client. Currently this capability can only be set and viewed using the configuration CLI. To add the capability follow these steps:

    • Start the command shell by running idsh command from the bin directory of your Curity Identity Server installation folder.

    • Enter configuration mode by running configure command.

    • Enter the following command. If you don’t use the default name for the Token Service change the token-service part of the path accordingly. If you named your client differently, change haapi-public-client to your client’s id.

      set profiles profile token-service oauth-service settings authorization-server client-store config-backed client haapi-public-client capabilities authorization-api-client
    • Enter commit command and exit the shell.

  6. The client must be a public client in order to use some functionality needed by the API. Is a public client. This means that in General section in Authentication Method it should have the value no authentication. Normally you can’t create a public client (with no authentication) and Client Credentials capability, but giving the client the authorization-api-client capability enables this. This means that you can change the Authentication Method to no authentication only after giving your client settings described in point 5.

  7. In the demo-client.html file in the examples/api-driven folder set proper client name and token endpoint URL. You should set it in the config map found around line 80. Enter the following values if you use the default Curity configuration and the client mentioned before:

const config = {
    clientId: 'haapi-public-client',
    tokenEndpoint: 'https://localhost:8443/oauth/v2/oauth-token'
}
  1. Still in the demo-client.html, around line 50, you can find the starting value for the authorization request. As this is an input field it can be changed when running the client, but for ease of use you can change the value here.

    If you use the default Curity configuration and the client settings mentioned above, use this value:

https://localhost:8443/oauth/v2/oauth-authorize?client_id=haapi-public-client&response_type=code&scope=read&state=foo&redirect_uri=https://localhost:7777/client-callback

Running the Demo

In order for the demo application to work it must be run from the same domain as the instance of Curity Identity Server. To achieve that, copy the two files - demo-client.html and demo-client.js - to the directory idsvr/usr/share/webroot in the folder where you run your Curity Identity Server from.

Here’s a video showing the demo application in action.

There are many authorization flows and methods that can be used with Curity Identity Server, it is thus important that the client should dynamically choose next steps in the authentication and authorization flow, and avoid hard-coding as much as possible.

Change behaviour and appearance of the authentication flow

One of the advantages of using API driven authentication is the ease of making changes in the behaviour and visual side of the client. All the responses from the API are sent as JSON, enabling you to display the results exactly as the client needs, not in a way they’ve been rendered by the backend. That is especially useful in case of native apps, as native components can be used to display steps of the authentication flow, instead of HTML.

Changing the behaviour

Currently, whenever the API sends a redirect response, we show it to the user and ask them to click to move further. This is done in the demo application to show each step separately. Normally the client would perform the redirects automatically. To achieve that, modify the file demo-client.js (remember to modify the file which is served from the webroot directory), go to line 317, and change the contents of the if statement:

if (apiRedirectUri) {
    console.log(`API redirect detected, URI is ${apiRedirectUri}`)
    apiRequest(apiRedirectUri)
} else {

Now, instead of seeing a Redirect component, the user will be redirected automatically to the new URI.

Changing the appearance

The demo client consists of a few different component-like functions which are responsible for creating appropriate DOM elements. These functions are called from the generatePage function. Let’s modify the Selector method so it displays some nice icons, instead of a list of names. Exchange the Selector method for the following:

function Selector(action) {
    const iconGoogle = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0MS42NiA0Mi41MSI+PGRlZnM+PHN0eWxlPi5jbHMtMXtmaWxsOiM1MTdiYmQ7fS5jbHMtMntmaWxsOiMzMWE3NTM7fS5jbHMtM3tmaWxsOiNmYWJiMDk7fS5jbHMtNHtmaWxsOiNlNzQzMzY7fTwvc3R5bGU+PC9kZWZzPjxnIGlkPSJMYXllcl8yIiBkYXRhLW5hbWU9IkxheWVyIDIiPjxnIGlkPSJMYWdlcl8xIiBkYXRhLW5hbWU9IkxhZ2VyIDEiPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTQxLjY2LDIxLjczYTE4LjEyLDE4LjEyLDAsMCwwLS40NS00LjM1SDIxLjI2djcuODlIMzNhMTAuNDMsMTAuNDMsMCwwLDEtNC4zNCw2LjlsMCwuMjYsNi4zMSw0Ljg5LjQzLDBjNC0zLjcsNi4zMy05LjE2LDYuMzMtMTUuNjMiLz48cGF0aCBjbGFzcz0iY2xzLTIiIGQ9Ik0yMS4yNiw0Mi41MWEyMC4yNCwyMC4yNCwwLDAsMCwxNC4wNy01LjE1bC02LjctNS4xOWExMi42MiwxMi42MiwwLDAsMS03LjM3LDIuMTIsMTIuOCwxMi44LDAsMCwxLTEyLjEtOC44M2wtLjI1LDBMMi4zNSwzMC41NmwtLjA4LjI0YTIxLjIzLDIxLjIzLDAsMCwwLDE5LDExLjcxIi8+PHBhdGggY2xhc3M9ImNscy0zIiBkPSJNOS4xNiwyNS40NmExMy4zMSwxMy4zMSwwLDAsMS0uNy00LjIsMTMuOSwxMy45LDAsMCwxLC42OC00LjIxdi0uMjhMMi40OCwxMS42MWwtLjIxLjFhMjEuMiwyMS4yLDAsMCwwLDAsMTkuMDlsNi44OS01LjM0Ii8+PHBhdGggY2xhc3M9ImNscy00IiBkPSJNMjEuMjYsOC4yMmExMS44LDExLjgsMCwwLDEsOC4yMiwzLjE2bDYtNS44NUEyMC4zNywyMC4zNywwLDAsMCwyMS4yNiwwYTIxLjIzLDIxLjIzLDAsMCwwLTE5LDExLjcxbDYuODcsNS4zNEExMi44NSwxMi44NSwwLDAsMSwyMS4yNiw4LjIyIi8+PC9nPjwvZz48L3N2Zz4=";
    const iconForm = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1Ny4xIDQzLjQ3Ij48ZGVmcz48c3R5bGU+LmNscy0xe2ZpbGw6I2ZmZjtzdHJva2U6IzYyNmM4Nzt9LmNscy0xLC5jbHMtM3tzdHJva2UtbWl0ZXJsaW1pdDoxMDt9LmNscy0ye2ZpbGw6IzYyNmM4Nzt9LmNscy0ze2ZpbGw6bm9uZTtzdHJva2U6IzY0NmU4Mjt9PC9zdHlsZT48L2RlZnM+PGcgaWQ9IkxheWVyXzIiIGRhdGEtbmFtZT0iTGF5ZXIgMiI+PGcgaWQ9IkxhZ2VyXzEiIGRhdGEtbmFtZT0iTGFnZXIgMSI+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMjgsNDNINC41YTMuODcsMy44NywwLDAsMS00LTMuNjl2LTMxSDI4LjU1Ii8+PHBhdGggY2xhc3M9ImNscy0xIiBkPSJNMjgsNDNINTIuNmEzLjg3LDMuODcsMCwwLDAsNC0zLjY5di0zMWgtMjgiLz48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0yOC41NSw4LjI5SDU2LjZWNC4xOUEzLjcsMy43LDAsMCwwLDUyLjkxLjVINC4xOUEzLjcsMy43LDAsMCwwLC41LDQuMTl2NC4xSDI4LjU1Ii8+PGNpcmNsZSBjbGFzcz0iY2xzLTIiIGN4PSI0Ljg4IiBjeT0iNC40IiByPSIxLjM3Ii8+PGNpcmNsZSBjbGFzcz0iY2xzLTIiIGN4PSIxMC42NCIgY3k9IjQuNCIgcj0iMS4zNyIvPjxjaXJjbGUgY2xhc3M9ImNscy0yIiBjeD0iMTYuNCIgY3k9IjQuNCIgcj0iMS4zNyIvPjxsaW5lIGNsYXNzPSJjbHMtMyIgeDE9IjE1LjkzIiB5MT0iMjIuNDUiIHgyPSIxNS45MyIgeTI9IjI5Ljc2Ii8+PHJlY3QgY2xhc3M9ImNscy0zIiB4PSIxMC4xOCIgeT0iMTkuMDUiIHdpZHRoPSI0MC41MyIgaGVpZ2h0PSIxNC4xOSIgcng9IjMuNCIvPjwvZz48L2c+PC9zdmc+";
    const iconDefault = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyOC40IDI4LjQiPjxkZWZzPjxzdHlsZT4uY2xzLTF7ZmlsbDpub25lO30uY2xzLTEsLmNscy0ye3N0cm9rZTojNjI2Yzg3O3N0cm9rZS1taXRlcmxpbWl0OjEwO30uY2xzLTJ7ZmlsbDojZmZmO308L3N0eWxlPjwvZGVmcz48ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIj48ZyBpZD0iTGFnZXJfMSIgZGF0YS1uYW1lPSJMYWdlciAxIj48cGF0aCBjbGFzcz0iY2xzLTEiIGQ9Ik0yMi42OSwyNS4xMXYtMmE0LDQsMCwwLDAtNC00aC04YTQsNCwwLDAsMC00LDR2MiIvPjxjaXJjbGUgY2xhc3M9ImNscy0yIiBjeD0iMTQuNjQiIGN5PSIxMS4wMyIgcj0iNC4wMiIvPjxwYXRoIGNsYXNzPSJjbHMtMSIgZD0iTTE0LjIuNUExMy43LDEzLjcsMCwxLDEsLjUsMTQuMiIvPjwvZz48L2c+PC9zdmc+";

    const parentElement = document.createElement('div');
    parentElement.classList.add('siimple-form');
    const titleElement = document.createElement('h3');
    titleElement.textContent = action.model.title;
    parentElement.append(titleElement);

    const optionsElement = document.createElement('div');

    action.model.options.forEach(option => {
        const linkElement = document.createElement('a');
        linkElement.style = "margin-right: 10px;";
        linkElement.href = "#";
        linkElement.onclick = () => apiRequest(option.href);
        const icon = document.createElement('img');
        icon.style = "height: 35px";

        switch (option.kind) {
            case 'google':
                icon.src = iconGoogle;
                break;
            case 'html-form':
                icon.src = iconForm;
                break;
            default:
                icon.src = iconDefault;
        }
        icon.title = 'Login with: ' + option.title;
        linkElement.append(icon);

        optionsElement.append(linkElement);
    });
    parentElement.append(optionsElement);
    return parentElement;
}

The selection screen will now show icons instead of names. What is more important, the change has been done only in the client code. There was no need to update any templates on the server side. This can, for example, allow you to have different clients displaying the authentication flows differently, while still using the same instance of the Curity Identity Server.

You can see the result of the changes in code in this short video:

Conclusion

Thanks to the demo client you can have a test drive of the Hypermedia Authentication API and quickly check what this feature allows you to do with the authentication flows. We’ve also shown how easy it is to tailor the authentication flows to your needs, by changing just a few lines of the client code.

Should you have any questions or comments on the API-driven authentication, don’t hesitate to contact us.

Let’s Stay in Touch!

Get the latest on identity management, API Security and authentication straight to your inbox.

Keep up with our latest articles and how-tos using RSS feeds