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 Systems
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.
In an OrderCloud solution, the storefront will be configured to interact with the OrderCloud API server for the relevant region and environment, as documented in OrderCloud Supported Regions and Environments, that hosts the marketplace instance.
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.
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.
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.
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.
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 against an API client configured with an IsAnonBuyer
flag and the default context user, which is used for resolving roles and not a user context when interacting with the OrderCloud API.
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.
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 simplifies custom development effort and complexity, which can also be regenerated after modifying the Commerce Engine to ensure the integrity of the library.
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.
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” |
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
- Sitecore: Bearer token authentication
- Sitecore: Authentication and authorization
- Sitecore: Configure the password policy
- OrderCloud: OrderCloud Supported Regions and Environments
- OrderCloud: Introduction to API Clients
- OrderCloud: Understanding Security Profiles
- OrderCloud: Authentication
- OrderCloud: Anonymous Shopping
- OrderCloud: Configuring Custom Password Security
Continue the Series
- Transitioning from Sitecore Experience Commerce to OrderCloud: Customers to Buyer Users
- Transitioning from Sitecore Experience Commerce to OrderCloud: Customers and Buyers – API Access
- Transitioning from Sitecore Experience Commerce to OrderCloud: Catalogs and Categories
- Transitioning from Sitecore Experience Commerce to OrderCloud: Sellable Items To Products
- Transitioning from Sitecore Experience Commerce to OrderCloud: Inventory and Pricing
- Transitioning from Sitecore Experience Commerce to OrderCloud: Carts to Unsubmitted Orders and Carts
- Transitioning from Sitecore Experience Commerce to OrderCloud: Fulfillments to Shipping
- Transitioning from Sitecore Experience Commerce to OrderCloud: Tax and Payments
- Transitioning from Sitecore Experience Commerce to OrderCloud: Orders
- Transitioning from Sitecore Experience Commerce to OrderCloud: Order Workflow and Minions
- Transitioning from Sitecore Experience Commerce to OrderCloud: Promotions