# Custom External Widget

This feature provides clients and partners the ability to acquire a user contextualized access token, while the user is logged into the Cornerstone LMS application.  This enables them to build custom pages, inside an IFRAME, that invoke Cornerstone APIs through server-side code they host on their servers.

Hosting server-side code on the client or partner's servers is required for acquiring the access token and invoking Cornerstone APIs

# Flow Diagram

Flow diagram of Authentication for Custom External Widgets

# Setup

# Oauth2 Application Registration

This process will remain unchanged from the client credentials flow, with exception of a visual indicator on the scopes lists, to indicate that certain scopes will be unavailable for the authorization code flow. Admin should capture the client and client secret presented at completion of the registration process.

For additional security, an optional field to specify sanctioned domain(s) is presented to the admin.  The domain(s) will be used to validate the domain of the IFrame URL in the new widget.

Manage OAuth 2.0 Applications configuration for Custom External Widgets

During the setup of the Client Credentials application registration, the admin is required to select a user account which the tokens are issued for.  When the same Client Id is used in an authorization code flow, the token will be issued for the logged in user and not the one assigned to the application.

For the initial implementation, applications registered with the new Assertion flow will not be available for custom page integration

# Custom Page Configuration

On the custom page setup, a new Custom External widget will be available.

Custom Page configuration for Custom External Widgets

Once this widget is selected the admin is prompted for the following information:

  • The admin selects an Oauth2 application from a list presented (only eligible ones are listed, see note above)

  • The number of scopes associated with the selected OAuth2 application is displayed

Best practice for security is to carefully select scopes when registering an Oauth2 application, if the intention is to use it for a custom page

  • The admin then enters the URL to the location where it is hosted, this will be the source of the Custom Page delivered into the IFRAME

The URL specified must be HTTPS, it will need to be validated as such

Custom External Widget settings in a Custom Page

# Authorization Code Acquisition

When the custom page is accessed by a user, the application will call the edge-sts-service internally to acquire a code. This code will be passed as a query string parameter to the external widget.

# Delivering the code to source of the IFRAME

Once the code is received by the CSX application, the custom page IFRAME is rendered with the source URL configured and code attached to it on the URL:

<iframe src="https://acme.com/iframeurl.jsp?code={code retrieved}&state={state}" title="Acme custom page"></iframe>

# Access Token Acquisition

The receiving server of authorization code will exchange it for a token by making a call to the OAuth2 token endpoint

The following parameters are required to acquire the access token

  • clientId  : From the OAuth2 application

  • clientSecret : From the OAuth2 application

  • code : Received from IFrame src

  • grant_type : must be "authorization_code"

  • state : Received from IFrame src

  • scope : Scopes requested for the currently logged in user

    • If all scopes are selected, only scopes assigned to the application will be selected

# Request to Oauth2 Token endpoint

JSON payload Post

curl -X POST \
 https://[corpname].csod.com/services/api/oauth2/token \
 -H 'Content-Type: application/json' \
 -H 'cache-control: no-cache' \
 -d '{
   "grantType": "authorization_code",
   "code": [code],
   "clientId": [clientId],
   "clientSecret": [clientSecret],
   "state": [state],
   "scope": [scope]
 }'

Validation

  • grantType must be "authorization_code"

  • clientId and clientSecret must be validated as valid

  • code must be associated with the clientId

  • The CSX session associated with the code must still be active

  • State must be a valid state given to the iframe for the current authorization code

  • Scope must be a valid, space delimited list of scopes, or the all scope.

Response

Successful

# Access token success
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: private
{
    "access_token": "ZWRnZQ:...",
    "expires_in": 86400,
    "scope": "...",
    "token_type": "Bearer"
}

Access Token Requirements

  • Access token will be issued with an expiration of 86400 seconds (24 hours)

  • Access token will be associated with the active session of the code

  • When the user's session expires or the user logs out, the access token must be invalidated

    • We may need to produce hooks through River to expose session events for expiration and log out

    • Subscribe to the session events for expiration and log out

Get UserInfo

In order to get the user information that corresponds to the above Token make the following call:

curl -X GET \
 https://[corpname]/services/api/oauth2/userinfo \
 -H 'Authorization: Bearer ZWRnZQ:...'

Note: above bearer token can then be used to make API call to return data for the contextual user.