web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :

SHA256 encryption for Business Central with Azure function

Andrey Baludin Profile Picture Andrey Baludin 3,941

Hello Team!

In this post we'll learn how to create Azure functions and call them from AL. As example I used SHA256 encryption. Demo was presented on our #NavTechDays session (Link).

1. Open your Azure portal and create new Function App resource

0456.1.JPG

Use Consumption plan as Hosting plan to pay only for function calls.

2. Open created Function App, select Functions and press New function

1732.2.JPG

3. Choose HTTP trigger template

3808.3.JPG

4. Input name for your function, choose Anonymous authorization level and press Create.

4064.4.JPG

5. Have a look on code in template:

4478.5.JPG

By default function could accept parameter Name in request string or as JSON body.

6. Click on Get function URL button, copy it and test with Postman.

GET method:

4087.6.JPG

POST method (do not forget to add Content-type: application/json header) :

0777.7.JPG

Works perfectly.

7. I have a task to pass some value and a key into the function and get back value encrypted with SHA256 algorithm. This implementation requires .NET so I can't make it with AL. I have next code in C/AL which I want to move to Azure function:

5557.9.jpg

8. I want to use GET method only in my Azure function, so I need to remove POST method in Integrate part of my function, and JSON parsing in code:

1348.12.JPG

9. Now I change the source code:

6138.10.JPG

Code to copy:

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Security.Cryptography;
using System;

public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string text = req.Query["text"];
    string key = req.Query["key"];

    ASCIIEncoding encoding = new ASCIIEncoding();

    Byte[] textBytes = encoding.GetBytes(text);
    Byte[] keyBytes = encoding.GetBytes(key);

    Byte[] hashBytes;

    using (HMACSHA256 hash = new HMACSHA256(keyBytes))
        hashBytes = hash.ComputeHash(textBytes);

    return key != null
        ? (ActionResult)new OkObjectResult(BitConverter.ToString(hashBytes).Replace("-", "").ToLower())
        : new BadRequestObjectResult("Please pass a key on the query string");
}

10. Let's pass new parameters and check our function again:

2818.8.JPG

11. Now it's time to integrate Business central with Azure function using HTTP Client.

I need table:

table 50115 "SHA256 Setup"
{
    DataClassification = ToBeClassified;

    fields
    {
        field(1; "Entry No."; Integer)
        {
            DataClassification = ToBeClassified;
            CaptionML = ENU = 'Entry No.';
        }

        field(4; "HMAC Key"; text[50])
        {
            DataClassification = ToBeClassified;
            CaptionML = ENU = 'HMAC Key';
        }
        field(5; "Signature API"; text[100])
        {
            DataClassification = ToBeClassified;
            CaptionML = ENU = 'Signature API';
        }

    }

    keys
    {
        key(PK; "Entry No.")
        {
            Clustered = true;
        }
    }
}


Page:

page 50115 "SHA256 Setup"
{
    PageType = Card;
    SourceTable = "SHA256 Setup";
    CaptionML = ENU = 'Hash Setup';
    ApplicationArea = All;
    UsageCategory = Administration;
    LinksAllowed = false;

    layout
    {
        area(content)
        {
            group(GroupName)
            {
                field("HMAC Key"; "HMAC Key")
                {
                    ApplicationArea = All;
                }
                field("Signature API"; "Signature API")
                {
                    ApplicationArea = All;
                }

                field(RequestText; RequestText)
                {
                    ApplicationArea = All;
                }

                field(HashText; HashText)
                {
                    ApplicationArea = All;
                    Editable = false;
                    MultiLine = true;
                }
            }
        }
    }
    actions
    {
        area(Processing)
        {
            action(SendText)
            {
                ApplicationArea = All;
                Caption = 'Send data to Azure function';
                Promoted = true;
                PromotedIsBig = true;
                PromotedCategory = Process;
                Image = Web;

                trigger OnAction();
                var
                    FuncMgt: Codeunit "SHA256 management";
                begin
                    HashText := FuncMgt.GetSignature(RequestText);
                end;

            }
        }
    }
    var
        RequestText: Text;
        HashText: Text;
}


And management codeunit:

codeunit 50115 "SHA256 management"
{
    trigger OnRun();
    begin
    end;

    procedure GetSignature(RequestText: Text) : Text;
    var
        SHA256Setup : Record "SHA256 Setup";
        URL : Text;
    begin
        SHA256Setup.get();
        SHA256Setup.TestField("Signature API");
        SHA256Setup.TestField("HMAC Key");
         
        URL := SHA256Setup."Signature API" + '?text=' + RequestText + '&key=' + SHA256Setup."HMAC Key";
        Exit(SendRequest(URL));
    end;

    local procedure SendRequest(URL : Text) ResponseText : Text;
    var
        Client : HttpClient;
        ResponseMessage : HttpResponseMessage;
    begin
        if not Client.Get(URL, ResponseMessage) then
            Error(Error001, 'GET');
        if not ResponseMessage.IsSuccessStatusCode() then begin
            ResponseMessage.Content().ReadAs(ResponseText);
            error(Error002, ResponseMessage.HttpStatusCode(), ResponseText);  
        end;

        ResponseMessage.Content().ReadAs(ResponseText);
        exit(ResponseText);        
    end;
    
    var
        Error001 : Label 'The %1 call to the web service failed.';
        Error002 : Label 'The web service returned an error message:\ Status code: %1\ Description: %2';
}


12. Publish your app and open HASH Setup page. Input your API URL, Key and Request text, press 'Send data to Azure function' action and you'll get encrypted value back:

4075.11.JPG

13. Hope now you have more detailed knowledge about Azure function usage and testing so try to create your own project!

Comments

*This post is locked for comments