Client authentication methods

Both Nexus Business Events and Data Sync make requests to clients in the customer's platform. When they do, they need to authenticate themselves. Here are the supported authentication methods.

Authorization types

The property AuthorizationType can take one of these values, and them requires additional properties:

Note!

We strongly recommend using the authorization type 'JwtFromUrl' wherever it is possible.

"JwtFromUrl"

The Nexus service will make a request to a url, creating a JWT, then use header

Authorization: Bearer <JWT>
Property Comment
PostUrl The open url to post PostBodyto
PostBody A string containing JSON with credentials for creating the token
PostContentType A string containing the Content-Type header for the POST request. Defaults to "application/json".
ResponseTokenJsonPath A json path to where the access token is in the response.
Note! The path is case sensitive; it matters if you use CamelCase, pascalCase, snake_case, etc.
TokenCacheInMinutes For how long the token will be cached before fetching a new one

Example

{
  "AuthorizationType": "JwtFromUrl",
  "PostUrl": "https://api.acme.com/Tokens",
  "PostBody": "{ 'ClientId': 'acme-api', 'ClientSecret': 'heimlichkeit' }",
  "ResponseTokenJsonPath": "Content.AccessToken"
}

"BearerToken"

A static token. The Nexus service will use header

Authorization: Bearer <token>
Property Comment
Token The static token

Example

{
  "AuthorizationType": "BearerToken",
  "Token": "..."
}

"Basic"

Basic authentication. The Nexus service will use header

Authorization: Basic <base64 string of "username:password">
Property Comment
Username The basic auth user name
Password The basic auth password

Example

{
  "AuthorizationType": "Basic",
  "Username": "acme-api",
  "Password": "dasheimlichkeit"
}

Two versions of the configuration

There are two ways to configure clients and authentications. You can use them in combination.

1. Separated Client and Authentication

Clients and authentication methods are listed separately. Clients can have custom RequestHeaders that will be used when calling them. A Client can reference an Authentication by it's id. Multiple clients can refer to the same Authentication.

INSERT INTO ServiceTenantConfiguration(Organization, Environment, Service, Configuration)
VALUES (@Organization, @Environment, 'businessevents', '{
    -- ...
    "Clients": [
        {
            "Name": "client-a",
            "Authentication": "standard-authentication"
        },
        {
            "Name": "client-b",
            "Authentication": "client-b-authentication",
            "RequestHeaders": { 
                "header-a": "value-a"
            }
        },
        {
            "Name": "client-c",
            "RequestHeaders": { 
                "Authorization": "some-custom-auth-mechanism"
            }
        }     
    ],
    "Authentications": [
        {
            "Id": "standard-authentication",
            "AuthorizationType": "JwtFromUrl",
            "PostUrl": "' + @BusinessApiUrl + '/api/v1//Authentication/Tokens",
            "PostBody": "{ ''ClientId'': ''smoke-api'', ''ClientSecret'': ''secsec'' }",
            "ResponseTokenJsonPath": "AccessToken"
        },
        {
            "Id": "client-b-authentication",
            "AuthorizationType": "Basic",
            "Username": "polyrythm",
            "Password": "beat201"
        }
    }
}')

2. Client centered

<client name>-authentication entries are used to define each Client's authentication. The special shared-client-authentications can be used to define authentications that are shared between clients.

(Note: no support for custom headers).

INSERT INTO ServiceTenantConfiguration(Organization, Environment, Service, Configuration)
VALUES (@Organization, @Environment, 'businessevents', '{
    -- ...
    "client-b-authentication": {
        "AuthorizationType": "Basic",
        "Username": "polyrythm",
        "Password": "beat210"
    },
    "shared-client-authentications": [
        {
            "AuthorizationType": "JwtFromUrl",
            "PostUrl": "' + @BusinessApiUrl + '/api/v1/Authentication/Tokens",
            "PostBody": "{ ''ClientId'': ''smoke-api'', ''ClientSecret'': ''BagChairHaze101'' }",
            "ResponseTokenJsonPath": "AccessToken"
            "UseForClients": [ "client-a", "client-c" ]
        },
        {
            "AuthorizationType": "Basic",
            "Username": "uname",
            "Password": "pwd",
            "UseForClients": [ "client-d", "client-e" ]
        }
    ]
}')

TODO
TODO: Man kan ha en kombination
TODO: BE config i Fundamentals

In the Transition Guide, you find the steps to take if you wish to convert to the new way with support for custom headers.

Configuration example

Here we illustrate how a set of clients can be configured. The example shows a nexus configuration for business-events. The details are explained below.

DECLARE @BusinessApiUrl NVARCHAR(1023) = '$(BusinessApiUrl)'

INSERT INTO ServiceTenantConfiguration(Organization, Environment, Service, Configuration)
VALUES (@Organization, @Environment, 'businessevents', '{
    "ConnectionString": "<BusinessEventsConnectionString>",
    "VerifyPublications": "true|false",
    "PublicationIdAtCallback": "<GUID>",
    "Clients": [
        {
            "Name": "client-a",
            "Authentication": "client-a-authentication"
        },
        {
            "Name": "client-b",
            "Authentication": "client-b-authentication",
            "RequestHeaders": { 
                "header-a": "value-a"
            }
        },
        {
            "Name": "client-c",
            "Authentication": "client-c-authentication"
        },
        {
            "Name": "client-d",
            "Authentication": "shared-client-authentication"
        },
        {
            "Name": "client-e",
            "Authentication": "shared-client-authentications"
        }     
    ],
    "Authentications": [
        {
            "Id": "client-a-authentication",
            "AuthorizationType": "Basic",
            "Username": "polyrythm",
            "Password": "beat210"
        },
        {
            "Id": "client-b-authentication",
            "AuthorizationType": "BearerToken",
            "Token": "$(BearerToken)"
        }
        {
            "Id": "client-c-authentication",
            "AuthorizationType": "JwtFromUrl",
            "PostUrl": "' + @BusinessApiUrl + '/api/v1/Authentication/Tokens/WwwFormUrlEncoded",
            "PostBody": "ClientId=smoke-api&ClientSecret=BagChairHaze101",
            "PostContentType": "application/x-www-form-urlencoded",
            "ResponseTokenJsonPath": "AccessToken"
        },
        {
            "Id": "shared-client-authentication",
            "AuthorizationType": "JwtFromUrl",
            "PostUrl": "' + @BusinessApiUrl + '/api/v1/Authentication/Tokens",
            "PostBody": "{ ''ClientId'': ''smoke-api'', ''ClientSecret'': ''BagChairHaze101'' }",
            "ResponseTokenJsonPath": "AccessToken"
        }
    ]
  }')

In this example we've configured five clients. 'client-a' is setup to use 'client-a-authentication' which is configured as basic authentication. 'client-b' is setup to use 'client-b-authentication' which is configured to be a bearer token. 'client-c-authentication', of type JwtFromUrl, is in turn configured to be used for 'client-c'. 'client-d' and 'client-e' is configured to use the same authentication, the 'shared-client-authentication' which in this case is configured as 'JwtFromUrl'.

(@BusinessApiUrl is a SQL variable setup from the Azure DevOps variable $BusinessApiUrl)