I am trying to get OAuth working with BC online, using POSTMAN (and have also tried dotnetcore). I'd appreciate any help, if anyone can see something I am doing wrong?
I have tried following a number of guides, videos, and Microsoft docs, and I can get an access token back, but am rejected with 401 on any API calls I attempt. Both POSTMAN and the dotnetcore app appear to generate tokens that seem valid, but they do not let me in.
I'll also note that this is a sandbox environment, acquired via the link here: https://learn.microsoft.com/en-us/dynamics365/business-central/dev-itpro/developer/devenv-get-started but I've named it "Production", which is why you'll see that in the queries.
Here are the links I've followed:
automation-apis-using-s2s-authentication
Youtube walkthrough by Erik Hougaard
I've registered Apps in Azure AD with the appropriate Application permissions (I do not want to use delegated, as I don't want a user to have to sign in):
I've registered my AAD in BC with basically all permissions possible:
I've tried to use the Grant Consent functionality via BC, and it ostensibly worked with the redirect URL I set up (still 401'd though), and I have tried without a redirect URL.
I set the app up as a single tenant, I've also tried it as a multi-tenant. Nothing seems to work when I simply try to call any API endpoint like so:
https://api.businesscentral.dynamics.com/v2.0/myGUID/Production/api/v2.0/companies
https://api.businesscentral.dynamics.com/v2.0/myGUID/Production/api/v2.0
Have also tried the odata endpoints.
This should be pretty straightforward so I'm not sure what I am missing? Anyone able to help? The latest jwt.ms decoding I have looks like this:
{
"typ": "JWT",
"alg": "RS256",
"x5t": "2ZQpJ3UpbjAYXYGaXEJl8lV0TOI",
"kid": "2ZQpJ3UpbjAYXYGaXEJl8lV0TOI"
}.{
"aud": "00000002-0000-0000-c000-000000000000",
"iss": "https://sts.windows.net/myGuid/",
"iat": 1664660352,
"nbf": 1664660352,
"exp": 1664664252,
"aio": "E2ZgYOAw1rymduL8q00/5jz4/z21FgA=",
"appid": "myCorrectAppId",
"appidacr": "1",
"idp": "https://sts.windows.net/myGuid/",
"oid": "oid",
"rh": "0.AVkABukwYKJWB0CCNK-Tk2gaCgIAAAAAAAAAwAAAAAAAAACdAAA.",
"sub": "beb41889-d36a-4ba3-98dd-fc8aa8b99a15",
"tenant_region_scope": "NA",
"tid": "myGUID",
"uti": "LEDbpEovbE2Nks34QjYTAA",
"ver": "1.0"
}.[Signature
In case it is useful here is the C# app:
HttpClient client = new HttpClient(); string tenantId = "redactedTenantId"; string url = "https://login.microsoftonline.com/{tenantId}/oauth2/token"; string clientId = "redactedClientId"; string secret = "redactedSecret"; var values = new Dictionary { {"grant_type", "client_credentials" }, {"client_id", clientId}, {"client_secret", secret}, {"scope", "https://api.businesscentral.dynamics.com/.default"} }; var content = new FormUrlEncodedContent(values); var response = client.PostAsync(url, content); var respString = response.Result.Content.ReadAsStringAsync().Result; JObject val = JObject.Parse(respString); string token = val["access_token"].ToString();
And as you can imagine I tried a similar set-up using POSTMAN's OAuth 2.0.