Als je webservices met OAUTH2 wilt gebruiken (bijvoorbeeld omdat Microsoft de andere opties niet meer aanraadt) kun je het volgende doen:

In Azure AD maak je een nieuwe appregistratie aan.  Dat kun je door zoals beschreven in https://www.poelgeest.org/joomla/index.php/tips-a-trucs/127-bc20-gebruik-azure-ad-openid-om-te-authenticeren.html

Daarna ga je naar je app registration:

  • Klik op authentication
  • Klik op Add a platform
  • zet bij Mobile and desktop applications het vinkje bij https://login.microsoftonline.com/common/oauth2/nativeclient aan
  • Klik op save
  • Ga naar Certificates & Secrets en klik op + New Client Secret
  • Kopieer de Value die je krijgt: deze krijg je hierna niet meer te zien
  • Ga naar API permission
  • Klik op +Add a Permission, en voeg de volgende API/Permission Names toe:
    • Dynamics 365 Business Central
      • Admincenter.ReadWrite.All (Application)
      • API.ReadWrite.All (Application)
      • App_access (Application)
      • Automation.ReadWrite.All (Application)
      • Financials.ReadWrite.All (Delegated)
      • User_impersonation (Delegated)
    • Microsoft Graph
      • User.Read (Delegated)
    • Klik op Grant admin consent for <tenant>

 

Op de server moet ook een instelling worden gewijzigd. Bij Valid Audiences moet naast de bestaande audience (wat als het goed is je applicationID is) ook de audience https://api.businesscentral.dynamics.com worden toegevoegd

  • Set-navserverconfiguration -serverinstance <serverinstance> -keyname “ValidAudiences” -keyValue “<huidige waarde>;https://api.businesscentral.dynamics.com”

Daarna kun je als gebruiker al OAUTH2 gebruiken om aan te melden op de API/Webservices.

Wil je Service2Service gebruiken, dan moet je nog het volgende doen:

  • Log in in Business Central
  • Ga naar Azure Active Directory Applications
  • Klik op + New
  • Voer als Client ID je Application ID in
  • Geef als description een duidelijke beschrijving in.
  • Geef de juiste rollen die nodig zijn (D365 ADMINISTRATOR en D365 BUS FULL ACCESS)
  • Klik op Grant Consent. Je moet nu inloggen in Azure en toestemming geven
  • Zet de State op Enabled

Er wordt dan een gebruiker aangemaakt met dezelfde naam als de beschrijving.

Nu kun je ook via S2S verbinding maken. Het tokenrequest moet de volgende keys bevatten:

Key grant_type, value client_credentials
Key client_secret, value <de Value die je hebt gemaakt bij Certificates & Secrets
Key client_id, value application ID
Key scope, value https://api.businesscentral.dynamics.com/.default

Je post dit naar https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token, waarmee je een token ontvangt. Dit token kun je dan weer gebruiken om een get-request te doen op de OdataURL van de Business Central omgeving.

 

Voorbeeldcode PureBasic voor het maken van de S2S verbinding:

body.s="grant_type=client_credentials&client_secret=<secret value>&client_id=<App/ClientID>&scope=https://api.businesscentral.dynamics.com/.default"
NewMap tokenheader.s()
tokenHeader("content-type")="application/x-www-form-urlencoded"
httprequest=HTTPRequest(#PB_HTTP_Post,"https://login.microsoftonline.com/<TenantID>/oauth2/v2.0/token",body.s,0,tokenheader())
Statuscode.s=HTTPInfo(httprequest,#PB_HTTP_StatusCode)
ErrorMessage.s=HTTPInfo(httprequest,#PB_HTTP_ErrorMessage)
token.s=""
Debug Statuscode
If Val(statuscode)>399
Output.s=statuscode+":"+ErrorMessage
Else
output.s=HTTPInfo(httprequest,#PB_HTTP_Response)
output=LTrim(output,"{")
output=RTrim(output,"}")
For teller=1 To CountString(output,",")+1
datastring.s=StringField(output,teller,",")
datastring.s=RemoveString(datastring,#DQUOTE$)
datakey.s=StringField(datastring,1,":")
datavalue.s=StringField(datastring,2,":")
Debug datakey
Debug datavalue
If datakey="access_token"
token.s=datavalue
Break
EndIf
Next teller
EndIf

FinishHTTP(HTTPRequest)
Debug output.s


If token.s
url.s="<odatav4 adres business central>"
NewMap requestheader.s()
requestheader("authorization")="Bearer "+token
httprequest=HTTPRequest(#PB_HTTP_Get,url.s,"",0,requestheader())
If httprequest
Statuscode.s=HTTPInfo(httprequest,#PB_HTTP_StatusCode)
ErrorMessage.s=HTTPInfo(httprequest,#PB_HTTP_ErrorMessage)
output.s=HTTPInfo(httprequest,#PB_HTTP_Response)
Debug statuscode
Debug errormessage
Debug output.s
FinishHTTP(httprequest)
EndIf
EndIf