Single Sign On via OpenID Connect
Published by Jeff Ilse on April 15, 2019
Last updated on November 9, 2022
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.
Properties | Description |
---|---|
| A URL where agents can get a user-specific JSON web token |
| A URL where users enter their IDP credentials |
| Required to access the urls above |
| Required 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.
Note: If you're using Azure B2C as your IDP, you'll need to update the policy level setting to use response_mode
form_post
. This will ensure Azure sends OrderCloud a POST
request containing the authorization code in the request body rather than a GET
request with the authorization code in the query parameters. Using any other response_mode
is not recommended for those using Azure B2C as their IDP due to the excessive length of authorization codes generated by Azure.
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://my-buyer-application.com/login?token={0}",
"AuthorizationEndpoint": "…",
"TokenEndpoint": "…",
"IntegrationEventID": "integrationeventID", // required for configs created after 03/31/2020
"CustomErrorUrl": "https://my-buyer-application.com/error?ErrorMessage={0}" // optionally redirect to a custom URL upon error
}
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. Standard OrderCloud roles and custom roles are valid. 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!
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:
{
"Username": "neworderclouduser", // username of the user created in OrderCloud
"ErrorMessage": null
}
/syncuser
(Optional) Called after a user enters their credentials in the IDP on subsequent 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 configuration 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:
{
"ErrorMessage": null
}
Note that in any of the responses your application sends back to OrderCloud, populating ErrorMessage
in your response will terminate the process.
Deep Linking
In some cases it may be desirable to redirect your user to a different part of your application upon logging in. For example, your marketing department might start sending out links to promotional products. Your user will click on one of these links and need to log in. Upon logging in your user will need go to the product detail page for that specific product instead of the home page.
To handle this you can add an optional appstartpath
query parameter to the relying party login URL.
https://sandboxapi.ordercloud.io/ocrplogin?id=<ID>&roles=<Roles>&cid=<ApiClientID>&appstartpath=/products/my-promotional-product
Then, modify your AppStartUrl
to include {2}
which will be replaced with whichever value you defined in appstartpath
. Make sure the value you pass is url-encoded.
For example if I want to redirect users to /products/myawesomeproduct
upon logging in then my relying party login URL would look like this:
https://sandboxapi.ordercloud.io/ocrplogin?id=<ID>&roles=<Roles>&cid=<ApiClientID>&appstartpath=%2Fproducts%2Fmyawesomeproduct
And my AppStartUrl would look like this:
https://my-buyer-application.com{2}?token={0}
Now once login via OpenID is successful OrderCloud will redirect your user to the URL that resolves to:
https://my-buyer-application.com/products/myawesomeproduct?token={yourordercloudtoken}
IDP Token
In addition to retrieving OrderCloud's token it is also possible to get the IDP token for the user logging in. You may use this token to perform additional API calls to that IDP directly. To do this simply add {1}
in your AppStartUrl
, this will be replaced with the IDP token.
For example:
https://my-buyer-application.com?token={0}&idptoken={1}
Now once login via OpenID is successful OrderCloud will redirect your user to the URL that resolves to:
https://my-buyer-application.com?token={yourordercloudtoken}&idptoken={youridptoken}
Note: If you're using Azure as your identity provider you will need to add the Azure ClientID to the "AdditionalIdpScopes" array on the OpenIDConnect Configuration otherwise you will not get an IDP access token
OrderCloud Refresh Token
If you wish to retrieve the OrderCloud refresh token along with the OrderCloud token you can add refresh={3}
. This will then be replaced with a valid OrderCloud refresh token.
For example:
https://my-buyer-application.com?token={0}&refresh={3}
Now once login via OpenID is successful OrderCloud will redirect your user to the URL that resolves to:
https://my-buyer-application.com?token={yourordercloudtoken}&refresh={yourordercloudrefreshtoken}
Note: You can only receive a refresh token if you have enabled your api client to allow refresh tokens by setting a refresh token duration.
Custom Error Redirect
If you wish to redirect a user to a custom page if an error occurs during authentication, you can add a value to CustomErrorUrl
within your OpenID Connect Configuration.
If an error occurs, OrderCloud will redirect the user to that custom error url.
For example:
https://my-buyer-application.com/error?ErrorMessage={0}
The error message {0}
will be replaced with the error text from OrderCloud.
Custom Query Parameters
If you wish to pass custom query parameters to GET /ocrplogin
that will populate in the AuthorizationEndpoint users are redirected to, you can add customParams={value}
for each custom query parameter. One example use case would be passing in a locale such as:
https://sandboxapi.ordercloud.io/ocrplogin?id=<ID>&roles=<Roles>&cid=<ApiClientID>&appstartpath=%2Fproducts%2Fmyawesomeproduct&customParams=locale%3Dus
Note: If you're using Azure B2C as your IDP, you'll need to include customParams=response_mode%3Dform_post
in your GET /ocrplogin
request. This will ensure Azure sends OrderCloud a POST
request containing the authorization code in the request body rather than a GET
request with the authorization code in the query parameters. Using any other response_mode
is not recommended for those using Azure B2C as their IDP due to the excessive length of authorization codes generated by Azure.
Still have questions?
Ask in our Community Channel