Using an external OAuth server with commercetools

04.07.2023

Introducing a new software into an already existing system landscape is never an easy task. One of the challenges is to reuse the existing user management. In this article we’re going to describe how we helped a customer to connect theirs with commercetools.

Initial Situation

Our customer already had a centralized user management system. Their goal was to provide their customers a seamless experience when switching between their different applications and their new store. They’re using an Azure identity provider (IDP) to realize that.

commercetools is a headless commerce platform. The platform is built on top of the MACH stack. MACH stands for:

  • Microservice
  • API-first
  • Cloud-native
  • Headless

All those principles help to make it very flexible. Additionally, their product offers a great API documentation.

Get your users into commercetools

In the first step we had to think about a way to sync users into commercetools. Unfortunately, there is no SCIM connecter which would have made this undertaking any easier. Instead, we built a custom connector. Due to the API-first nature and the microservice approach of commercetools, it felt like their intended solution. User and groups are modelled as customer and customer groups in commercetools. At the moment, only one customer can be part of a group, but that was sufficient for our use case. There are different ways to use the groups, but we used them to represent the role of the user.

{
    "key": "<unique-identifier-from-JWT>",
    "customerNumber": "CR007",
    "email": "john.doe@example.com",
    "firstName": "John",
    "lastName": "Doe",
    "authenticationMode": "ExternalAuth",
    "customerGroup": {
        "typeId": "customer-group",
        "key": "user"
    }
}

If you take a similar approach to ours, you should take yourself some time to think about the right “key” for creating your customers. This will help you to access your customers easier. The Azure IDP returns an access token in the JWT format and one information in it is an unique identifier of the user. We’re using this identifier as the keys for our customers in commercetools.

Another important detail is shown in the request above. In line 7 you can see the attribute “authenticationMode” set to “ExternalAuth”. This is necessary if you want to use an external authentication for your customer.

Our custom connector does not only create but also update customers if necessary.

The external auth flow

The commercetools documentation provides a good overview of how to use an external auth. One important information is that it will affect your performance, another one is that commercetools is using the OAUTH2 introspect endpoint and it should take less than 500ms to respond.

At this point we were facing two issues. The Azure IDP didn’t support the introspect endpoint and if it had, it would have had to return the scopes that the commercetools api understands. We solved those problems by implementing a custom /introspect endpoint.

The diagram above shows an example of how our solution works: First the user logs in and the Azure IDP returns an access token. This access token is then used to retrieve products. Calling the products endpoint is just an example and it works the same way for all other endpoints as well. When the commercetools API receives the request, it needs to validate the access token. It normally does that using the commercetools auth server but since we configured commercetools to use the external auth, it requests our custom introspect endpoint. Our custom introspect endpoint checks whether the access token is valid or not and which scopes are assigned to the user. If the access token is valid and the user has the right permission the commercetools api will return the requested products. Otherwise, it will return an error.

Integrating commercetools with your existing user management system is easy

I hope this post showed you how easy it is to reuse to connect commercetools with your existing user management and it gave you some ideas how to solve the problems that might occur when you try to connect yours. Feel free to reach out if you have any questions about our solution.

Zurück zur Übersicht

5 Kommentare zu “Using an external OAuth server with commercetools

  1. Hi Maximilian, Thanks for the reply.
    We are thinking of not using a token introspection for Auth and using client credentials flow for Cart and Order creation. Do you see any flaws in this approach?
    So, a CT customer will be created before a cart is created. The customer password will be set to a *static password*. A cart will be created using client_credentials flow and customerId will be set in subsequent requests. So, there is no token introspection involved!
    We are thinking of using commeretools carts API which is client credentials flow https://docs.commercetools.com/api/projects/carts
    rather than My Carts API (/me/carts) which is Customer Auth flow and involves Token introspection.
    Thanks.

  2. Hi Jay,

    the short answer is that we create the users in advance and not during the introspection endpoint call. Keep in mind that you only have 500 ms before the call runs into a timeout.

    We built a custom connector. The custom connector is connected to the existing user management system. The user management system itself provides events to which our custom connector is listening.

    When a user is created or updated in the user management system, an event is emitted. The custom connector receives the event and processes it. It’s mostly a data mapping with some simple additional logic.

    Best regards,
    Max

  3. Hi Maximilian, Thanks for the article, it’s really helpful! Just trying to understand when you create the customer (customer connector) in commercetools if it’s not already there? is it during introspection or there is a separate flow for it?
    Thanks.
    Jay

  4. Hi Vishal,

    unfortunately, I can’t share the source code, but I can give you more details.

    First you need to understand how the introspect endpoint works. You can find it’s specification here: https://datatracker.ietf.org/doc/html/rfc7662. You can name the endpoint however you want but we sticked to the name “/introspect”. The token will be part of the body as shown in the following curl request:

    curl –request POST \
    –url /introspect \
    –header ‚Content-Type: multipart/form-data‘ \
    –form token=

    You can also find other examples in the specification.

    The next example shows a response when the token is valid ({projectKey} is just a placeholder for this example):

    {
    „active“: true,
    „scope“: „view_products:{projectKey} view_categories:{projectKey} manage_my_orders:{projectKey}”
    }

    If the token is invalid, you simply set active to false and don’t return any scopes.

    In our “introspect endpoint” implementation we first check if the token is valid, extract the unique identifier from the access token, request the customer’s group and then map the group to the matching commercetools scopes.

    Caution: If you’re using the customer groups from commercetools to represent the user roles you can simply call the customers endpoint which returns the customer group but you have to make sure that you’re using an api client instead of the passed access token because otherwise you would create a loop.

    I hope this helped. Feel free to ask any questions I left unanswered.

    Best regards,
    Max

  5. Hello Maximilian Göke,
    Thanks for the article it really helped in understanding the integration of External OAuth with Commercetools. Could you please provide more details on how was the custom introspect done? Some example will be really helpful.
    Thanks & Regards,
    Vishal

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*Pflichtfelder

*