Implementing SSO via OpenID Connect

Suggest an edit
Jeff Ilse

Updated by Jeff Ilse

December 21st, 2021

SSO (Single Sign On) allows your users to authenticate themselves to the OrderCloud API by logging into any identity provider you trust. For example, let shoppers save addresses and orders on your site by logging in with Google or Facebook. Or, save your customer service reps the hassle of one more login screen by providing a single sign on point through your ERP system.

OpenID Connect

Single sign on is made possible by OpenID Connect. The OpenID Connect protocol specifies a series of RESTful API exchanges between two parties, an Identity Provider (IDP) like Google and a Relying Party (RP) like OrderCloud. This guide will not describe that full protocol, instead it will teach you how to configure OrderCloud to to trust an IDP to provide user authentication.

Configuring Your Identity Provider (IDP)

Whether you are using a service like Google's API or you have written your own IDP implementation, OrderCloud will need the same four pieces of information from your IDP.

PropertiesDescription
TokenEndpointA URL where agents can get a user-specific JSON web token
AuthorizationEndpointA URL where users enter their IDP credentials
ConnectClientIDRequired to access the urls above
ConnectClientSecretRequired to access the urls above

API Reference: Create an OpenID Connect Configuration

The Client ID and especially the Client Secret should be private. The URLs can be public, for example, Google's URLS. In turn, your IDP will need a piece of information from OrderCloud called an Authorized Redirect URI. Use the value

https://sandboxapi.ordercloud.io/ocrpcode

This OrderCloud resource accepts the IDP's access token, converts it to an OrderCloud token, and then redirects users to the AppStartUrl you will specify in the next section.

Configuring OrderCloud (RP)

Step 1: Create an OpenID Connect Integration Event

OrderCloud requires an OpenID Connect Integration Event to be setup in order to use SSO via OpenID Connect. This will require hosting two endpoints, such as in your own middleware application. These endpoints are discussed in further detail below in the Configuring Your Integration Event Code section.

API Reference: Create an Integration Event

Step 2: Create Connection Configuration

Each connection configuration enables users to authenticate to one Ordercloud ApiClient through one IDP. The Ordercloud API supports normal CRUD operations on these configurations.

API Reference: Create an OpenID Connect Configuration

POST https://sandboxapi.ordercloud.io/v1/openidconnects HTTP/1.1
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Content-Type: application/json

{
    "ID": "anormalordercloudid",
    "OrdercloudApiClient": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "ConnectClientID": "…",
    "ConnectClientSecret": "…",
    "AppStartUrl": "https://mysinglpagebuyerapp.com/login?token={0}",
    "AuthorizationEndpoint": "…",
    "TokenEndpoint": "…",
    "IntegrationEventID": "integrationeventID" // required for configs created after 03/31/2020
}

The fields from the IDP will not be validated until a user attempts to log in, so testing is critical. The field AppStartUrl is used to redirect to your front-end app after login; the characters {0} will be replaced with a valid Ordercloud token.

Implementing Login

Users are now ready to authenticate. Link them to this URL

https://sandboxapi.ordercloud.io/ocrplogin?id=<ID>&roles=<Roles>&cid=<ApiClientID>

where <ID> matches the ID field of the configuration object above, <ApiClientID> matches the OrdercloudAPIClient field, and <Roles> is a space separated list of roles requested. Users will be redirected to an IDP route to provide credentials. If the credentials are valid, users will be redirected again to AppStartUrl with a valid Ordercloud token in the URL. Your front-end application will need to handle grabbing this token from the URL and storing it. But otherwise, they have been granted a valid OrderCloud access token!

Deep Linking

You'll notice that a successful login via the OpenID connect flow will always send the user to your AppStartUrl.

This is not always desirable. For example, your marketing department might start sending out links to promotional products. Your user will click on one of these links and might need to log back in. Upon logging in your user will go to the home page instead of the originally intended link.

To handle this you can add an optional appStartPath query parameter to the ocrplogin URL.

https://sandboxapi.ordercloud.io/ocrplogin?id=<ID>&roles=<Roles>&cid=<ApiClientID>&appStartPath=/products/my-promotional-product

Now once login via OpenID is successful OrderCloud will redirect your user to the URL that resolves to:

{AppStartUrl}/products/my-promotional-product

Configuring Your Integration Event Code

The OpenID Connect Integration Event requires hosting two endpoints in your own application that will be triggered throughout the authentication flow.

/createuser Called after a user enters their credentials in the IDP for the first time while accessing your application. This endpoint will receive the following request body from OrderCloud:

  "ExistingUser": null,
  "OpenIdConnect": {}, // your OpenID Connect configruation you created
  "TokenResponse": {
    "id_token": "eyJhbGciOiJSU...", // token from your IDP
    "access_token": "ya29.a0ARrdaM92vGZsFj"
  },
  "Environment": "Sandbox",
  "OrderCloudAccessToken": "eyJhbGciOiJSU...", // token of the default context user of your API Client for your middleware
  "ConfigData": null

Using the token response from your IDP, you can decode the token and use the data provided to create a user in OrderCloud. After the user is created, this endpoint will need to send back the following response:

{
  "HttpStatusCode": 200,
  "Username": "neworderclouduser", // username of the user created in OrderCloud
  "ErrorMessage": null,
  "UnhandledErrorBody": null,
  "xp": {}
}

/syncuser (Optional) Called after a user enters their credentials in the IDP on subseuqnt attempts to access your application after having done so successfully at least once. This endpoint will only be called if CallSyncUserIntegrationEvent is true in your OpenID Connect config. It will receive the following request body from OrderCloud:

  "ExistingUser": {}, // existing OrderCloud user
  "OpenIdConnect": {}, // your OpenID Connect configruation you created
  "TokenResponse": {
    "id_token": "eyJhbGciOiJSU...", // token from your IDP
    "access_token": "ya29.a0ARrdaM92vGZsFj"
  },
  "Environment": "Sandbox",
  "OrderCloudAccessToken": "eyJhbGciOiJSU...", // token of the default context user of your API Client for your middleware
  "ConfigData": null

Using the token response from your IDP, you can decode the token and use the data provided to update the existing user in OrderCloud. After the user is update, this endpoint will need to send back the following response:

{
  "HttpStatusCode": 200,
  "ErrorMessage": null,
  "UnhandledErrorBody": null,
  "xp": {}
}

Note that in any of the responses your application sends back to OrderCloud, you can return a non-successful HttpStatusCode and optional error details to terminate the process.