Http web request SSL validation

You may need to communicate with external web component in Nav, such API like E.commerce or other applications. To do that you can use code unit 1297 for simple page or Rest API and code unit 1290 for Soap API.

I find out that Http Web request component from Microsoft .Net frame work don’t allow you to communicate with any web service that have SSL auto signed certificat (this is a kind of low cost https, sales by ovh for example) because there are not as secure as true SSL certificate.

I find the following video posted by ms that explain how to intercept certificate validation in HttpWebRequest component : https://www.youtube.com/watch?v=NW_ZiW6J790

I’ve created the C# DLL to force all SSL validation on System.Net.HttpWebRequest

HttpCertificateValidator.dll.zip
HttpCertificateValidator Source.zip

How to use it :

Simply copy HttpCerticiateValidator.dll in the Nav service Add-in folder (will be used server side).

In C/AL declare a DotNet variable Assembly Dynamic NAV / HttpCertificateValidator and class HttpCerticiateValidator.RequestValidator.

Before sending the request (HttpWebRequest.Getresponse) call the Request validator constructor with HttpWebRequest in parameter. This will simply overide the .Net ssl verification function to accept all certificate.

You can modify standard cu 1290/1297 or create your own code unit to manage web communication. This example send a Rest request with json content and read the response content, handling utf8 encoding and multi chunk response :

// Http request header
DotNetGHttpWebRequest := DotNetGHttpWebRequest.Create('http://...');
DotNetGHttpWebRequest.Method := 'GET';
DotNetGHttpWebRequest.KeepAlive := FALSE;
DotNetGHttpWebRequest.Accept := '*/*';
DotNetGHttpWebRequest.Timeout := 60000;
DotNetGHttpWebRequest.ContentType := 'application/json;charset=utf-8';

// Http request body exemple for Rest API :
// Convert text to bigtext to handle encoding
BigTextL.ADDTEXT('{ "name": "json example" }');

// Generate encoded stream containing request body content
RecLBlob.INIT;
RecLBlob.Blob.CREATEOUTSTREAM(OutStreamL, TEXTENCODING::UTF8);
BigTextL.WRITE(OutStreamL);
RecLBlob.Blob.CREATEINSTREAM(InStreamL);
DotNetLRequestStream := DotNetGHttpWebRequest.GetRequestStream;
COPYSTREAM(DotNetLRequestStream, InStreamL);
DotNetLRequestStream.Flush;
DotNetLRequestStream.Close;
DotNetLRequestStream.Dispose;

// Force SSL Certificat validation
HttpCertificateValidator := HttpCertificateValidator.RequestValidator(DotNetGHttpWebRequest);

// Try to send request and get response :
DotNetGHttpWebResponse := DotNetGHttpWebRequest.GetResponse;

// Read response :
TempBlob.INIT;
TempBlob.Blob.CREATEINSTREAM(InStreamL);
DotNetGHttpWebResponse.GetResponseStream.CopyTo(InStreamL);

// Read response until last chunk
IntLRead := 1;
WHILE IntLRead > 0 DO BEGIN
  IntLRead := InStreamL.READTEXT(TxtLChunkRead); 
  IF IntLRead > 0 THEN
    TxtGResponse := TxtLChunkRead;
END;

// Close Http web request 
DotNetGHttpWebResponse.Close;

// Handle response
IF TxtGResponse [...]

Variables needed :
DotNetGHttpWebRequest – DotNet – System.Net.HttpWebRequest
DotNetLEncoding – DotNet – System.Text.Encoding
DotNetLRequestStream – DotNet – System.IO.Stream
BigTextL  – BigText
RecLBlob – Record – TempBlob
TempBlob – Record – TempBlob
TxtLChunkRead – Text
TxtGResponse – Text
IntLRead – Integer

 

Leave a Reply

Your email address will not be published. Required fields are marked *