Using the OAuth Assistant in a Single Page Application

Using the OAuth Assistant in a Single Page Application

tutorials

Curity provides a JavaScript assistant for OAuth that supports the Assisted Token-, Implicit- and Code Flow as well as logout and session management. The assistant is available on NPM and can easily be added to a project with the command: npm install @curity/oauth-assistant A simple example application is embedded within the npm package itself. This article will use the example in order to showcase how to use the assistant in a Single Page Application (SPA).

Setting up the example

The steps needed to get the example running are:

  1. Install the oauth-assistant
  2. Install dependencies to run the example
  3. Start the example app
  4. Make modifications specific to the environment

To install the assistant with the example, install dependencies and start the app, run:

npm install @curity/oauth-assistant
cd node_modules/@curity/oauth-assistant/
npm install
npm start

The defaults can now be modified in /example/index.js. Change parameters such as base_url, client_id, issuer, allowed_origins, etc. as needed. These can be found starting on line 60.

Initializing the Assistant

In order to initialize the assistant a settings object is passed in. An example of this is available in /example/index.js starting on line 60. Details of the settings can be found in the documentation for the assistant itself on NPM. The settings configure things such as the issuer, what client to use, what flow to use, how framing should be configured, etc.

const authorizeSettings = {
    base_url                : "https://localhost:8443",
    client_id               : "oauth-assistant-client",
    issuer                  : "https://localhost:8443/oauth/v2/oauth-anonymous",
    redirect_uri            : window.origin + "/assisted.html",
    for_origin              : window.origin,
    flow_type               : "code",
    iframe                  : {
        targetElement       : 'body',
        width               : null, // take default value
        height              : null, // take default value
        backdrop            : {
            visible         : true, // default is true
            style           : null, // take default value
            backdropClass   : "backdrop-class"
        }
    },
    allowed_origins         : ["https://localhost:8443", "http://localhost:8080"], // default is [window.origin]
    check_session_iframe    : null,
    session_polling_interval: 5, // polling interval in seconds, default is 5
    allowed_jwt_algorithms  : ['RS256'],
    jwt_sig_public_key      : { // allowed formats are jwk | jwks_uri | pem | issuer | metadata_url | raw
        format              : 'issuer', // in case of issuer, the issuer value will be taken from jwt payload
        value               : null
    },
    debug                   : false,
};

Methods

The assistant makes 4 methods available that can be used to initiate an authorization flow. There are 4 methods in addition to that to get tokens, revoke tokens and logout the user from the server.

  1. authorize(parameters)
  2. authorizeFrame(parameters)
  3. authorizeHiddenFrame(parameters)
  4. authorizeHiddenFallbackToVisible(parameters)
  5. getToken()
  6. getIDToken()
  7. revoke()
  8. logout(postLogoutRedirectUri)

Optional parameters

The methods for authorization take a parameters object as input. This can be any number of optional parameters to pass in with the authorization call. When using the example app these options can be set on the app page. An example:

{
    "scope" : "openid",
    "state" : "123",
    "prompt": "login"
}

Configuring the Curity Identity server

A client supporting the flows to be used have to be configured in the Curity Identity Server. The Implicit Flow and Code Flow are described in the respective articles.

Note also that the Authentication method for the client has to be set to no-authentication in order for the example app to work. In addition to that make sure to correctly configure Redirect URIs, Allowed Origins and Allowed Post Logout Redirect URIs according to the environment the example app is running in.

If the openid scope is requested in the parameters in order for an ID token to returned, the openid scope also needs to be configured on the client in the Curity Identity Server. If an ID token is returned, the client needs to have its own ID in the audiences list if audiences are explicitly configured. Otherwise, the ID token will have the wrong audience and be rejected. By default no audiences are explicitly configured when creating a client in the Curity Identity Server and the ID of the client will be used as the audience automatically.

An example configuration is available in the example-config section.

Note

The example included has all 3 flows configured for convenience. This would most likely not be the case in a live deployment where they would be configured on separate clients instead.

Running the flows using the example app

When the assistant has been initialized with the correct settings, the optional parameters configured, and the Curity Identity Server set up the supported flows can be tested using the example app.

Login Flow with Redirect

When executing this flow, the browser should invoke the configured Authenticator(s) and after successful authentication redirect to the redirect URI. When the flow executes a code is received behind the scene and is automatically redeemed for an Access token and ID token (if requesting openid scope). The Show Token and Show ID Token can be used to display the tokens issued.

Note

Login with Redirect cannot be used with the Assisted token Flow.

Login Flow with visible frame

This flow will present the configured Authentication in a frame. Note here that if SSO is enabled there might already be an SSO session available and in that case the frame will likely just flash by quickly on the screen and no Authentication is needed. In order to force authentication, the "prompt" : "login" parameter can be added. Alternatively, the logout URL of the server can be called, ex. https://localhost:8443/authn/authentication/logout.

After successful Authentication the issued token will be displayed.

Issued Token

Login Flow with hidden frame

This flow is very similar to the Login Flow with visible frame when using the example app. It uses the method authorizeHiddenFallbackToVisible(parameters) and hence will fall back to showing a framed Authentication if there is no SSO session available. When an SSO session is available no frame is loaded.

Revoke Token

This calls the revoke endpoint to revoke the current token. When called the Show Token flow will show No Token.

Show token

This will show the token issued from an earlier executed Authorization flow by calling the getToken() method of the assistant.

Show ID token

This will show an ID token issued by an earlier Authorization flow by calling the getIDToken() method. Note that an ID token is only issued when passing the "scope" : "openid" parameter and when using the Code Flow.

Logout

This will call the logout method and with that call the logout endpoint of the server and log out the session. No Access or ID Token will be shown after a successful logout. More details on the Logout process can be found in the article OpenID Connect Single Logout.

Short demo

Example config

This example configuration can be imported and merged into an instance of the Curity Identity Server and would represent what has been used as an example in this article.

<config xmlns="http://tail-f.com/ns/config/1.0">
  <profiles xmlns="https://curity.se/ns/conf/base">
    <profile>
      <id>authentication-service</id>
      <type xmlns:auth="https://curity.se/ns/conf/profile/authentication">auth:authentication-service</type>
      <settings>
        <authentication-service xmlns="https://curity.se/ns/conf/profile/authentication">
          <authenticators>
            <authenticator>
              <id>html1</id>
              <html-form xmlns="https://curity.se/ns/conf/authenticators/html-form">
                <account-manager>default-account-manager</account-manager>
                <credential-manager>default-credential-manager</credential-manager>
              </html-form>
            </authenticator>
          </authenticators>
        </authentication-service>
      </settings>
    </profile>
    <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>oauth-assistant-client</id>
                <no-authentication>true</no-authentication>
                <redirect-uris>http://localhost:8080/assisted.html</redirect-uris>
                <redirect-uris>http://localhost:8080/</redirect-uris>
                <scope>openid</scope>
                <user-authentication>
                  <allowed-authenticators>html1</allowed-authenticators>
                  <allowed-post-logout-redirect-uris>http://localhost:8080/assisted.html</allowed-post-logout-redirect-uris>
                </user-authentication>
                <allowed-origins>https://localhost:8443</allowed-origins>
                <allowed-origins>http://localhost:8080</allowed-origins>
                <capabilities>
                  <code/>
                  <implicit/>
                  <assisted-token/>
                </capabilities>
              </client>
            </config-backed>
          </client-store>
        </authorization-server>
      </settings>
    </profile>
  </profiles>
</config>

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