Build Your Own SSO

The Kids’ SSO app is designed to provide a single-sign on experience for all the applications on your platform. By centralizing user sign in, registration, and account management, you can provide a secure & consistent experience for kids across your platform, based on the industry standard OAuth 2.0 authorization protocol.

We provide our SSO app implementation out of the box as part of KWS, but in rare cases it may be desirable to build & host your own fully customizable version. This document outlines how you can achieve that.

OAuth 2.0 basics

The SSO app provided is designed to let users activate their accounts with any KWS-integrated application in your platform. In order to get the most out of KWS, we strongly recommend that you build your own SSO app in the same way, so our SSO app makes use of the following query parameters throughout:

  • clientId: Public identifier for the app the user is authenticating in. This can be used with the Get App Config endpoint to get the data for the app, including branding details & an app ID which is required for user activation.
  • redirectUri: This is the URL to redirect successfully authenticated users to once they’ve activated their account with the app. This will be checked against the server when authenticating, and the request will be rejected if it doesn’t match a URL added to the app via the Control Panel.

App Config

When the SSO app is initialised, it should use the clientId passed in the query params to retrieve the configuration of the app from the API. This configuration includes important information for showing branding of the app and for verifying the redirect URI.

curl -X GET \
  https://{API_URL}/v1/apps/config?oauthClientId=<appClientId> \
  -H 'Content-Type: application/json' \
  -H 'Accept-Language: en' \
  -H 'Accept: application/json, text/plain, */*'

See Get App Config for all options.

Registration

In order to register a user, you need a form to take a username and password. Depending on the configuration of your app, it will likely also require a date of birth and a parent’s email address. The form data should be submitted to the Create User endpoint.

curl -X POST \
  https://{API_URL}/v2/users \
  -H 'Content-Type: application/json' \
  -d '{
    "username": "MyUsername",
    "password": "password",
    "parentEmail": "myparent@superawesome.com"
  }'

Once the user has been registered successfully, the SSO app must log the user in and activate them in the app before an auth code can be retrieved and sent back to the app. For instructions on doing this, follow the Login instructions below.

Login

To log a user in, first the Password grant must be used to gain an access token with SSO scope. This can be done by calling the /oauth/token endpoint:

curl -X POST \
  https://{API_URL}/oauth/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept-Language: en' \
  -H 'Authorization: Basic c3VwZXJhd2Vzb21lY2x1YjpzdXBlcmF3ZXNvbWVjbHVi' \
  -H 'Accept: application/json, text/plain, */*' \
  -d 'grant_type=password&username=<username>&password=<password>'

In the response, once successfully authenticated, you will receive an access token in the form of a JSON Web Token (JWT). If you inspect the JWT, you will notice that it has the scopes ‘sso’ and ‘user’. This token shouldn’t be exposed outside of the SSO app, but can be stored and used to retrieve an auth code which can be returned to the application and used to get a token with the right scope.

Note

It is recommended to store this token in some way, eg. in Localstorage, so it can be used later by the user if they return to the app and wish to log in again, or if they wish to manage their account.

Note

For this endpoint you must use basic authentication via the Authorization header as in the above example.

Once you have this SSO token you can call the authorise endpoint:

curl -X POST \
  https://{API_URL}/oauth/authorise \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'Accept-Language: en' \
  -H 'Accept: application/json, text/plain, */*' \
  -H 'Authorization: Bearer <token>' \
  -d 'response_type=code&client_id=<appClientId>&redirect_uri=<appRedirectUri>'

On getting a successful response, redirect the user to the same redirect URI passed to this request.

If you get a 403 error response from this request, it means the user has not been activated in the application yet. Follow the instructions in the Activation section below to activate the user, then attempt the login request again.

Activating an application

Whether the user has just created an account or is logging in to an existing account, they must be activated in the app before they can be authenticated and provided with a token scoped to the app.

In order to activate the user in the app, make a request to the Activation endpoint:

curl -X POST \
  https://{API_URL}/v1/users/<userId>/apps \
  -H 'Content-Type: application/json' \
  -H 'Accept-Language: en' \
  -H 'Accept: application/json, text/plain, */*' \
  -H 'Authorization: Bearer <token>' \
  -d '{"username":"<username>","appName":"<appClientId>","permissions":[]}'

Forget/Reset password

The SSO app also provides functionality for users to reset their password. In order to implement this behaviour in your own application, you will need to implement two separate pages in your application: 1. A page to collect the user’s username & trigger the forgot password email, and 2. A page to reset the user’s password.

Please note that for both of the endpoints described in this section, sending the ID of your application in the appName parameter is optional, and will be used to apply your app-specific branding to the emails which we send.

Forgot password

Firstly, you will need to call the Forgot Password endpoint, providing the target username and optionally the client ID of your application. This will trigger an email to be sent to the child (or the parent, if the child has no email address associated with their account), which will contain a link containing a password reset token.

Note

You will need to ask your implementation manager to correctly configure the reset password URL in order for these generated emails to link to your custom SSO app!

curl -X POST \
  https://{API_URL}/v1/users/forgot-password \
  -H 'Content-Type: application/json' \
  -H 'Accept-Language: en' \
  -H 'Accept: application/json, text/plain, */*' \
  -d '{"username":"<username>","appName":"<optional appName>"}'

Note

Please note that for security reasons, this endpoint always returns 204 No Content, regardless of whether or not the user specified exists in KWS.

Reset password

Once the user has clicked on the link in the email and landed on your reset password page, your application will need to extract the password_reset_token query parameter from the URL, and use this to call the Reset Password endpoint, along with the user’s new password and optionally the client ID of your application.

This endpoint will trigger an email to be sent to the child (or parent, if the child has no email address associated with their account) confirming the password change.

curl -X POST \
  https://{API_URL}/v1/users/reset-password \
  -H 'Content-Type: application/json' \
  -H 'Accept-Language: en' \
  -H 'Accept: application/json, text/plain, */*' \
  -d '{"token":"<token>","newPassword":"<newPassword>","appName":"<optional appName>"}'

Delete User

Giving users the opportunity to delete their accounts is an important part of GDPR compliance, so your SSO app must provide a means for users to delete their accounts. In order to delete the user’s account on their behalf, you can call the Delete Account endpoint, specifying the user’s ID in the URL and their password in the request body.

Note

Please note that when calling this endpoint, you must provide an access token which has the sso scope (such as that obtained via the login endpoint - see the login section above for more details).

curl -X POST \
  https://{API_URL}/v1/users/{USER_ID}/delete-account \
  -H 'Content-Type: application/json' \
  -H 'Accept-Language: en' \
  -H 'Accept: application/json, text/plain, */*' \
  -H 'Authorization: Bearer <token>' \
  -d '{"password":"<password>"}'