Troubleshooting LS Central Using Service-to-Service (S2S) Authentication

In this article

User permissions

Testing the S2S Setup

Error publishing web services

Multi-tenant setup

Company names with empty space

User permission

The user must have sufficient permission. The best way to start is to assign the user with a SUPER equivalent permission set, because at this point you do not know which objects the permission set must have.

The super user permission set cannot be assigned to this user, so you must create a new permission set based on the SUPER permission set.

  1. Create a new Permission Set, name it Super_S2S, for example.
  2. Copy the existing super permission set, and assign that to the S2S user.
  3. You can refine this permission set, if needed.

Testing the S2S Setup

The following is a PowerShell script that you can use to test the S2S setup:

#########################
# Variables to update
#########################
$clientid = ""
$clientsecret = ""
$tenant = ""
$environmentName = ""
$companyName = ""
#########################
# Other variables
#########################
 
# Get access token
$body = @{grant_type="client_credentials";scope=$scope;client_id=$ClientID;client_secret=$ClientSecret}
$oauth = Invoke-RestMethod -Method Post -Uri $("https://login.microsoftonline.com/$tenant/oauth2/v2.0/token") -Body $body
$oauth.access_token

If the access token is a valid one, you should be able to get the list of companies by running the following script:

# Get companies
$companies = Invoke-RestMethod `
-Method Get `
-Uri $("$baseurl/api/v2.0/companies") `
-Headers @{Authorization='Bearer ' + $oauth.access_token}
 
foreach ($company in $companies.value) {
$company.id + " - " + $company.displayName
}

To test the web services connection, you can run these lines:

# Test WS connection
try
{
$ws_url = "$baseurl/WS/$companyName/Codeunit/TestConnection"
$headers = @{
"Authorization" = "Bearer " + $oauth.access_token
}
$response = Invoke-WebRequest -UseBasicParsing `
-Method Post `
-Uri $("$ws_url") `
-Headers $headers
$response
}
catch {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$reader.ReadToEnd()
}

Error publishing web services

500 - Internal Server Error

If you get this error message, 500 - Internal Server Error, when you click the Subscriber action on the Web Service Setup page, the error can have been caused by a user permissions issue.

  • Check the user setup in the Azure Active Directory Application Card, and make sure it has the proper permissions.

To check the failure reason, run these lines:

# Test Web Services subscription
try
{
$ws_url = "$baseurl/WS/$companyName/Codeunit/RetailMessageGetActiveList"
$headers = @{
"Authorization" = "Bearer " + $oauth.access_token
}
$response = Invoke-WebRequest -UseBasicParsing `
-Method Post `
-Uri $("$ws_url") `
-Headers $headers
$response
}
catch {
$reader = New-Object System.IO.StreamReader($_.Exception.Response.GetResponseStream())
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$reader.ReadToEnd()
}

Common issues

Response: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">a:Microsoft.Dynamics.Nav.Service.SOAP.ServiceBrokerException</faultcode><faultstring xml:lang="en-US">Service "Codeunit/RetailMessageGetActiveList" was not found!</faultstring><detail><string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Service "Codeunit/RetailMessageGetActiveList" was not found!</string></detail></s:Fault></s:Body></s:Envelope>

Reason: The user configured in the Azure Active Directory Application Card does not have proper permissions (review the setup).

Response: <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><s:Fault><faultcode xmlns:a="urn:microsoft-dynamics-schemas/error">a:Microsoft.Dynamics.Nav.Types.NavPermissionException</faultcode><faultstring xml:lang="en-US">You do not have the following permissions on XmlPort LSCRetailMSGGetActiveListXML: Execute.

To view details about your permissions, see the Effective Permissions page.

To report a problem, refer to the following server session ID: '42060'.</faultstring><detail><string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">You do not have the following permissions on XmlPort LSCRetailMSGGetActiveListXML: Execute.

To view details about your permissions, see the Effective Permissions page.

To report a problem, refer to the following server session ID: '42060'.</string></detail></s:Fault></s:Body></s:Envelope>

Reason: The user is not configured in the Azure Active Directory Application Card and does not have the proper permissions or consent was not granted (check Troubleshooting - User permissions).

Http Error to [GET: 

https://api.businesscentral.dynamics.com/v2.0/<tenant id>/<Environment Name>/WS/<Company Name>/services

If you get this error message, Http Error to [GET: https://api.businesscentral.dynamics.com/v2.0/<tenant id>/<Environment Name>/WS/<Company Name>/services?Tenant=<tenant id>, when you click the Publisher action on the Web Service Setup page, in a Sandbox environment, it might be because the LS Central extension is not allowed to make web services calls.

To check that, open the LS Central extension card in the Extension Management page and enable the field Allow HttpClient Requests.

For more information, see Precautions for sandbox environments with production data.

Multi-tenant setup

Note: The application and Business Central must be on the same AAD (Azure Active Directory). They can be on different tenants, but setup only works if they are both in the same AAD.

Company names with empty space

When you create the web service URL in Web Service Setup, for company names with a blank space in it, like LS Retail for example, make sure you replace the space with %20 to avoid creating an incorrect URL. The correctly entered company name now reads LS%20Retail instead.

Http Error to [POST: / Http Error (400): 'Bad Request' to [Post:

If you get this error message - Http Error to [POST: https://api.businesscentral.dynamics.com/v2.0/<tenant id>/<Environment Name>/WS/<Company Name>/TestConnection, when you click the Test Web Connection action, you need to look at the URI related to the token:

If the token retrieval URI is listed in the error, it means the system is not able to retrieve the token for the Service-To-Service (S2S) authentication for some reason.

In the image, the tenant ID is default. This is supposed to be used for on-premises installations only.

In SaaS, the URI is supposed to be like this: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token, where the tenant ID should match the customer's environment tenant ID.

If the tenant ID is not correct, that is because the tenant ID is not properly set on the Web Service Setup or the Distribution Location pages that are being used when testing the connection. The tenant ID is not being read on the TenantWeb Server Tenant fields, but from the Tenant parameter that should be included to the value in the Web Service URI field.

For a SaaS URI, the Web Service URI should have the following format: https://api.businesscentral.dynamics.com/v2.0/1c7cbf82-aa4a-49a5-97cf-6103dc32716f/Production/WS/HybridServerTest/Codeunit/RetailWebServices?Tenant=1c7cbf82-aa4a-49a5-97cf-6103dc32716f. The ?Tenant=1c7cbf82-aa4a-49a5-97cf-6103dc32716f is automatically added to the Web Service URI field when you fill in the other fields.

Note: You should not fill in the Web Service URI field directly, because you might forget to set the Tenant parameter in the URI and this kind of error might occur.

See also

Video Tutorial: S2S Authentication - Step 3.1

Video Tutorial: S2S Authentication - Step 3.2