How to Send a POST HTTP Request from Business Central to a Third-Party Application Using OAuth 2.0

How to Send a POST HTTP Request from Business Central to a Third-Party Application Using OAuth 2.0

Integrating Microsoft Dynamics 365 Business Central with third-party applications often requires secure communication. OAuth 2.0 is a widely used authorisation framework that enables secure API access. This article demonstrates a scenario of how to send a POST HTTP request from Business Central to a third-party application using OAuth 2.0.

1. Set Up OAuth 2.0 Credentials

To integrate with a third-party application, you need:

  • A - Client ID and Client Secret provided by the third-party application
  • B - Authorization Endpoint/ Token Endpoint URLs
  • C - API Endpoint to send the POST request
  • D - Scopes required by the third-party application.

2. Create an HTTP Client and Token Retrieval Logic

In Business Central, you can use the HttpClient, HttpRequestMessage, and HttpResponseMessage data types for HTTP communication. OAuth 2.0 access tokens are retrieved from the token endpoint by providing client credentials.

procedure GetAccessToken(): Text
    var
        vHTTPClient: HttpClient;
        vHttpResponseMessage: HttpResponseMessage;
        vHttpRequestMessage: HttpRequestMessage;
        RespText: Text;
        AccessToken: Text;
        vHttpContent: HttpContent;
        vHttpHeaders: HttpHeaders;
        JsonObject: JsonObject;
        JToken: JsonToken;
        TokenUrl: Text;
        StatusCode: Integer;
        JsonBody: Text;
        IsSucces: Boolean;
    begin

        //information obtained from the third party application
        TokenUrl := 'https://auth.com/token';

        jsonbody := '{"grant_type":"' + 'client_credentials' + '",';
        jsonbody += '"client_id":"' + 'xyz' + '",';
        jsonbody += '"client_secret":"' + 'abc' + '"}';

        vHttpContent.GetHeaders(vHttpHeaders);
        vHttpContent.WriteFrom(JsonBody);
        vHTTPClient.DefaultRequestHeaders.Add('Accept', 'application/json');
        vHTTPClient.DefaultRequestHeaders.Add('User-Agent', 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36');
        vHttpHeaders.Remove('Content-Type');
        vHttpHeaders.Add('Content-Type', 'application/json');

        vHttpRequestMessage.SetRequestUri(TokenUrl);

        if not vHttpClient.Post(TokenUrl, vHttpContent, vHttpResponseMessage) then
            Error('BssiFailedAccessTokenErr %1', GetLastErrorText());

        if not vHttpresponsemessage.IsSuccessStatusCode() then
            Error('IsSuccessStatusCode %1', vHttpresponsemessage.IsSuccessStatusCode());

        //Reading the access token from the response
        if vHttpResponseMessage.IsSuccessStatusCode() then begin
            vHttpResponseMessage.Content().ReadAs(RespText);

            Clear(JsonObject);
            JsonObject.ReadFrom(RespText);
            JsonObject.Get('access_token', JToken);
            JToken.WriteTo(AccessToken);
            AccessToken := DelChr(AccessToken, '=', '"');
            exit(AccessToken)
        end;        

Postman configuration of generating an access token.

3. Send the POST Request to the API Endpoint

Once you have the access token, use it to authenticate your POST request to the API endpoint. The POST request was to send one record from Business Central to the other application's database. Furthermore, the third-party application's primary key was recorded in the business central database's field.

codeunit xxxxx PostRequestAuthentication

//permission to write the primary key
{
    Permissions = TableData "Approval Entry" = rimd;
    trigger OnRun()
    begin
    end;

//event Subscriber that identifies a new record has added and sends the POST request
    [EventSubscriber(ObjectType::Table, Database::"Approval Entry", 'OnAfterInsertEvent', '', true, true)]
    procedure ApprovalEntryOnAfterInsertEvent(var Rec: Record "Approval Entry")
    var

    begin
       if (Rec."Table ID" = 38) AND ((Rec.Status = Rec.Status::Open) or (Rec.Status = Rec.Status::Created)) AND (Rec."Document Type" = Rec."Document Type"::Order) then
            SendPOSTRequest2(Rec);
    end;

    procedure SendPOSTRequest2(Rec: Record "approval entry")
    var
        Tbl_ApprovalEntry: REcord "Approval Entry";
        AccessToken: Text;
        PurchaseHeader: Record "Purchase Header";
        Purchaseline: record "Purchase Line";
        v2HttpResponseMessage: HttpResponseMessage;
        v2HttpRequestMessage: HttpRequestMessage;
        v2HttpContent: HttpContent;
        v2ContentHeaders: HttpHeaders;
        PostJsonObject: JsonObject;
        v2HTTPClient: HttpClient;
        postJsonBody: Text;
        URL: text;
        v2Httpheaders: httpheaders;
        vendorname: text;
        podescription: text;
        multipartbody: textbuilder;
        amounttext: text;
        systemID: text;
        Where: text;
        Which: text;
        creator: text;
        ponumber: text;
        which2: text;
        where2: text;
        cardid: JsonObject;
        cardidtext: text;
        response: text;
        jsontoken: jsontoken;
        responseid: text;
        which3: text;
        where3: text;
        status: text;
    begin

//getting the data from the Business central Table
        AccessToken := GetAccessToken();

//removing characters of some values of the data retrieved
        Where := '<>';
        which := '{}';
        which2 := '\';
        where2 := '=';
        where3 := '=';
        which3 := ',';

//specifying the parameters of the Json Object's body
        systemID := delchr(rec.SystemId, where, which);
        ponumber := rec."Document No.";
        creator := delchr(rec."Sender ID", where2, which2);
        amounttext := delchr(Format(rec."Amount (LCY)"), where3, which3);

        if AccessToken = '' then
            Error('Failed to retrieve access token.');

//creating the data array
        begin
            MultiPartBody.AppendLine('{"title":' + '"' + StrSubstNo('%1 / %2 / %3 / %4', rec."Document No.", creater, podescription, vendorname) + '"' + ',');
            MultiPartBody.AppendLine('"pONumber":' + ponumber + ',');
            MultiPartBody.AppendLine('"amounttext":' + '"' + amounttext + '"' + ',');
            MultiPartBody.AppendLine('"vendor":' + '"' + vendorname + '"' + ',');
            MultiPartBody.AppendLine('"senderID":' + '"' + creator + '"' + ',');
            MultiPartBody.AppendLine('"systemID":' + '"' + systemID + '"' + ',');
            MultiPartBody.AppendLine('"pOCreatedBy":' + '"' + creator + '"' + ',');
            MultiPartBody.AppendLine('"pODescription":' + '"' + podescription + '"');
            MultiPartBody.AppendLine('}');
        end;
        postjsonbody := MultiPartBody.ToText();

//sending the request with the HTTP request with the body 
        v2HttpContent.GetHeaders(v2HttpHeaders);
        v2HttpContent.WriteFrom(postJsonBody);
        v2HTTPClient.DefaultRequestHeaders.Add('Accept', 'application/json');
        v2HTTPClient.DefaultRequestHeaders.Add('User-Agent', 'Mozilla5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36'/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36');
        v2HTTPClient.DefaultRequestHeaders.Add('Authorization', 'Bearer' + ' ' + AccessToken);
        v2HttpHeaders.Remove('Content-Type');
        v2HttpHeaders.Add('Content-Type', 'application/json');
        
        URL := 'https://applicationendpointURL.com';

//sending the request
        if v2HttpClient.Post(URL, v2HttpContent, v2HttpResponseMessage) then begin
            v2HttpResponseMessage.Content().ReadAs(cardidtext);

//reading the response
            Clear(cardid);
            cardid.ReadFrom(cardidtext);
            CARDID.Get('id', jsontoken);
            jsontoken.WriteTo(id);

//writing the third party primary key to the Business Central
            rec.id := id;
            Tbl_ApprovalEntry.init;
            Tbl_ApprovalEntry.Reset;
            Tbl_ApprovalEntry.setrange("Entry No.", Rec."Entry No.");
            if Tbl_ApprovalEntry.Find('-') then begin
                Tbl_ApprovalEntry.id := id;
                Tbl_ApprovalEntry.modify;
               end
               
            end;
        end;        

Postman configuration of generating an access token.

4. Secure Storage of Credentials

  • Use Azure Key Vault or a secure configuration table in Business Central to store sensitive credentials such as the Client ID and Client Secret.


Satheesh kumar

Lead Technical Consultant at Tech One (Pvt)Ltd

3 周

Very informative Article.

回复
Indusara Liyanaarachchi

Solution Developer. Microsoft business central 365

3 周

Interesting

回复
Jarurran Muneeswaran

Quantity Surveyor | B.Sc. (Hons.) in Quantity Surveying | Cost Management | Specialized in CostX, PlanSwift, and CubiCost

1 个月

Interesting

要查看或添加评论,请登录

Ishini Saparamadu的更多文章

社区洞察

其他会员也浏览了