Transitioning from Sitecore Experience Commerce to OrderCloud: Customers and Buyers – API Access

 94 views

In this article, we will review and compare API Access for Sitecore Experience Commerce customers and OrderCloud buyer users to facilitate developers looking to transition from XC to OrderCloud as well as identify a path for migration of existing XC solutions to OrderCloud.

We will look at a high-level comparison of architecture, functionality, and data models, with greater focus on transitioning from Sitecore Experience Commerce, meaning identifying a close path to parity in OrderCloud, using the Habitat catalog and SXA Storefront.

Conceptual Architecture and Features

Storefront API Access to the Commerce Engine

One aspect that developers tend to glaze over is how an SXA storefront interacts with the Commerce Engine. This is because the installation scripts apply the necessary configurations for the installed topology without the need for further manual intervention.

Resources

In the Commerce Engine, the CommerceODataController actions are registered to either the /api or /commerceops route, which creates the API under these two primary resources. The api route typically hosts actions that a storefront or the Commerce Business Tools (BizFx) would request, while the commerceops route hosts actions for dev ops interactions by dev ops users and the commerce data provider.

In OrderCloud resources are not grouped up into resource buckets, however in the OrderCloud portal there is logical grouping within the UI to help navigate between related resources, as seen in figure 1.

For storefront users, the /me and /order resources will cover account management and creation of orders respectively.

Figure 1: Logical grouping of resources in the OrderCloud portal.

Authentication

The Sitecore Identity Server provides bearer token authentication for SXA storefront requests made to the Commerce Engine using the Commerce Engine Connect client, which is configured across Sitecore, Sitecore Identity Server, and Commerce Engine applications.

Figure 2: XC Authentication of Commerce Engine Connect for SXA storefront - Commerce Engine communications.

SXA customer registration and login functionality is accomplished using the SQL authorization provider, instead of the Sitecore Identify Server. This also segregates customer authentication data stored in the security database from commerce data stored in the commerce database.

The related commerce customer entity is created in the commerce database during account creation and the commerce customer reference is stored against the customer account in the security database.

Figure 3: Storefront users are created with a corresponding commerce customer entity to segregate membership data from commerce data.

In an OrderCloud storefront implementation, authentication is handled within OrderCloud itself using API clients, in a similar fashion to Sitecore Identity Server's clients, returning limited lifetime bearer tokens.

Figure 4: OrderCloud authentication via API client overview.

Storefront user data is stored under a single object and users are typically authenticated directly with all subsequent requests containing the context of a storefront user.

Roles and Authorisation

Requests to the Commerce Engine will see the bearer token validated, which will determine the roles of the authenticated user and compare them to the roles of the API resource, which is configured in the Commerce Engine under the ControllerMethodRolesPolicy in Global.json.

{
  "$type": "Sitecore.Commerce.Core.ControllerMethodRolesPolicy, Sitecore.Commerce.Core",
  "ControllerMethodRegularExpression": "/commerceops/",
  "AuthorizedRoles": [
    "sitecore\\Commerce Business User",
    "commerce\\runtime"
  ]
},
{
  "$type": "Sitecore.Commerce.Core.ControllerMethodRolesPolicy, Sitecore.Commerce.Core",
  "ControllerMethodRegularExpression": "/api/",
  "AuthorizedRoles": [
    "sitecore\\Commerce Business User",
    "commerce\\runtime"
  ]
}

Requests not containing an authorized role will be rejected by the Commerce Engine with the exception of the Commerce Engine Connect client being a special case in that the Commerce Engine identifies this user and appends the commerce\runtime role to the request context to effectively brute force authorisation for its requests.

In contrast, OrderCloud has predefined roles for the various resources, which is detailed further in Understanding Security Profiles, providing more granular control over the resources a user has access to.

During the authentication process the roles are resolved from the user being authenticated, based on security profile assignments at the company, user group, and user levels.

To replicate the behaviour from XC, while having considerations for the necessary restrictions to API resources that wouldn't be utilised by a storefront user, the following roles would be assigned to a security profile for storefront users.

{
  "Roles": [
    "Shopper",
    "MeAdmin",
    "MeXpAdmin",
    "MeAddressAdmin",
    "MeCreditCardAdmin",
    "PasswordReset"
  ]
}

Anonymous and Registered Users

In the SXA storefront, the customer id of anonymous/guest users and registered customers are passed in as a request header, which the Commerce Engine then resolves to the anonymous or registered user.

In OrderCloud, the user context needs to be resolved at the time of authentication, which will then be passed on to subsequent requests via the access token. Registered users are authenticated with username and password, while anonymous users are authenticated using the default context user an IsAnonBuyer flag configurations of the API client. Anonymous users only utilise the default context user for resolving roles and will not interact with OrderCloud using the default context user as the user context.

In figure 5, we see an API client configured with the IsAnonBuyer set as true and the DefaultContextUserName set to BUYER USER A. The roles configured to Security Profile A, which is assigned to Buyer A will be resolved when attempting to authenticate a registered buyer user or an anonymous user.

BUYER USER A is created for the specific purpose of being the anonymous user template as using a real user that can be modified or deleted at any time can have adverse effects on the anonymous user behaviour.

Figure 5: API client - buyer - security profile relationship and configuration example for registered and anonymous storefront users.

Service Proxy vs SDKs and Catalyst

The SXA storefront solution, including custom code, typically communicates with the Commerce Engine via the Service Proxy - an SDK containing Commerce Engine data models and strongly typed wrappers for the API. The Service Proxy simplies custom development effort and complexity, which can also be regenerated after modifying the Commerce Engine to ensure the integrity of the library.

Figure 6: Commer Engine API access via the Service Proxy.

OrderCloud also provides a JavaScript and .Net SDK for the OrderCloud data models and strongly typed wrappers for all public endpoints. The JavaScript SDK allows requests to be made directly from the client browser rather than passed through middleware, whereas the .Net SDK is intended for the middleware for requests that typically require wrapped logic or even placeholder wrappers to insert logic at a later date.

The OrderCloud catalyst is another .Net library which provides additional helpers for authentication, performant bulk requests, error handling, jobs, project setup, etc.

Figure 7: OrderCloud API access via SDK and Catalyst libraries.

Data Mapping

With the conceptual analysis above, we will now review what data mapping would look like for migration and from a comparison standpoint.

In the XC Entity/Component column, components are assumed to live on the primary XC entity being mapped.

OrderCloud IDs do not allow spaces. It is important that the IDs are parsed to remove/replace invalid characters consistently.

Security Profile

The security profile mapped below represents storefront users only. The BizFx Business Tools users would have a different configuration, most notably for roles.

OC Property Data Type Required XC Entity/Component XC Property Data Type Notes
ID string No Site (Sitecore) Domain string
Name string Yes Site (Sitecore) Domain string
Roles array No Shopper, MeAdmin, MeXpAdmin, MeAddressAdmin, MeCreditCardAdmin, PasswordReset N/A N/A
CustomRoles array No N/A N/A N/A
PasswordConfig.LimitPasswordReuse integer No N/A N/A N/A
PasswordConfig.MaxConsecutiveDupeChars integer No N/A N/A N/A
PasswordConfig.MaximumPasswordAge integer No N/A N/A N/A
PasswordConfig.MinimumPasswordAge integer No N/A N/A N/A
PasswordConfig.AllowedFailedAttempts integer No (web.config)
configuration/system.web/
membership/add[name="sql"]
maxInvalidPasswordAttempts string Set to 5
PasswordConfig.LockoutDuration integer No N/A N/A N/A
PasswordConfig.UpperCaseRequired boolean No N/A N/A N/A
PasswordConfig.LowerCaseRequired boolean No N/A N/A N/A
PasswordConfig.SpecialCharacterRequired boolean No N/A N/A N/A
PasswordConfig.NumericRequired boolean No N/A N/A N/A
PasswordConfig.MinimumCharacterCount integer No (Commerce.XA) Registration.cshtml
RegistrationUserInputModel.cs
data_val_length_min
MinimumLength
string
integer
Sitecore's default value is 6, while OrderCloud has a minimum value of 10.

Security Profile Assignment

OC Property Data Type Required XC Entity/Component XC Property Data Type Notes
SecurityProfileID string Yes Site (Sitecore) Domain string
BuyerID string No Site (Sitecore) Domain string
SupplierID string No N/A N/A N/A
UserID string No N/A N/A N/A
UserGroupID string No N/A N/A N/A

Buyer User (Anonymous User)

The anonymous buyer user is created to represent an instance of an anonymous user. This user is fleshed out with hard-coded values for mandatory properties.

OC Property Data Type Required XC Entity/Component XC Property Data Type Notes
buyerID string Yes Site (Sitecore) Domain string Is a resource parameter, not body property.
ID string No N/A N/A string "anonymous-user"
Username string Yes N/A N/A string "{buyerId}-anonymous-user"
Password string No N/A N/A N/A
FirstName string Yes N/A N/A N/A "Anonymous"
LastName string Yes N/A N/A N/A "User"
Email string Yes N/A N/A N/A "anonymous@user.com"
Phone string No N/A N/A N/A
TermsAccepted string No N/A N/A N/A
Active boolean Yes N/A N/A N/A Set to true
xp object No N/A N/A N/A

API Client

OC Property Data Type Required XC Entity/Component XC Property Data Type Notes
ClientSecret string No N/A N/A N/A
AccessTokenDuration integer Yes N/A N/A N/A Set to 600 (maximum)
Active boolean No N/A N/A N/A Set to true
AppName string Yes Site (Sitecore) Domain string
RefreshTokenDuration integer No N/A N/A N/A
DefaultContextUserName string No Anonymous Buyer User (OrderCloud) Username string
AllowAnyBuyer boolean No N/A N/A N/A
AllowAnySupplier boolean No N/A N/A N/A
AllowSeller boolean No N/A N/A N/A
IsAnonBuyer boolean No N/A N/A N/A Set to true
OrderCheckoutIntegrationEventID string No N/A N/A N/A
MinimumRequiredRoles array No N/A N/A N/A
MinimumRequiredCustomRoles array No N/A N/A N/A
MaximumGrantedRoles array No N/A N/A N/A
MaximumGrantedCustomRoles array No N/A N/A N/A
xp object No N/A N/A N/A

API Client Assignment

Technically, the API client assignment can be skipped and the AllowAnyBuyer property on the API client can be set to true instead, however this example creates an API client per storefront, which may be preferrable to allow the API client configuration to be modified later without affecting the other storefronts.

OC Property Data Type Required XC Entity/Component XC Property Data Type Notes
ApiClientID string Yes Api Client (OrderCloud) ID string
BuyerID string No Site (Sitecore) Domain string
SupplierID string No N/A N/A N/A

References