Getting Started with AS4 (EDI Integrator)

Requirements: EDI Integrator

Introduction

EDI Integrator offers a simple way to add AS4 capabilities to your application. AS4 functionality consists of two components: AS4Client and AS4Server. This guide details the common operations of both including code examples.

The component support several AS4 profiles. These include:

  • Standard (the OASIS Standard AS4 Profile)
  • ENTSOG
  • e-SENS

AS4Client may be used to initiate a request from your application to a server. The component can both send files (push) and receive files (pull).

The AS4Server component implements server-side processing of AS4 messages. It may be used to receive files from a client (push), respond to a client's request for files (pull), and also handles generating and verifying receipts.

The AS4Server component is designed to be easily integrated into a HTTP server, such as ASP.NET, but may also be used outside of a web server. The examples below assume the component is used within an environment where there is an HTTP context.

Contents

AS4Client: Sending Files

To send files with AS4Client (push), call the SendFiles method. This will send the files specified by EDIData to the specified URL.

Before calling SendFiles set AgreementRef to the agreement identifier used by both parties. Set AS4From and AS4To. EDIData specifies the file(s) to be sent. To encrypt the data set RecipientCerts. To sign the data set SigningCert. The SignerCert property should be set to verify the signed receipt.

When SendFiles is called the file(s) will be sent and any returned receipts will be verified.

Synchronous Receipts

To indicate that a synchronous receipt is expected set ReceiptReplyMode to rrmSync. The following properties are applicable when calling SendFiles with an agreement specifying a synchronous receipt (a receipt provided in the response):

  • AgreementRef
  • AS4From
  • AS4To
  • EDIData
  • URL
  • RecipientCerts (required to encrypt)
  • SignerCert (required to verify signed receipts)
  • SigningCert (required to sign files)
  • ConversationId (optional)
  • EncryptionAlgorithm (optional)
  • LogDirectory (optional)
  • MessageId (optional)
  • MessageProperties (optional)
  • Profile (optional)
  • ReceiptReplyMode
  • Service (optional)
  • ServiceType (optional)
  • SignatureAlgorithm (optional)

SendFiles Example (synchronous receipt):

client.Profile = As4clientProfiles.ebpfENTSOG;

//Specify the agreement and party information
client.AgreementRef = "http://agreements.company.com/sign_and_encrypt";

client.AS4From.Role = "Sender";
client.AS4From.Id = "org:b2b:example:company:A";

client.AS4To.Role = "Receiver";
client.AS4To.Id = "org:b2b:example:company:B";
      
//Configure the component to expect a synchronous receipt.      
client.ReceiptReplyMode = As4clientReceiptReplyModes.rrmSync;

//Company A's private certificate. Used to sign the outgoing message and files.
client.SigningCert = new Certificate(CertStoreTypes.cstPFXFile, 
    "C:\\files\\CompanyA.pfx", "password", "*");

//Company B's public certificate. Used to encrypt the outgoing file.
client.RecipientCerts.Add(new Certificate("C:\\files\\as4\\CompanyB.cer"));

//Company B's public certificate. Used to verify the signed receipt.
client.SignerCert = new Certificate("C:\\files\\as4\\CompanyB.cer");

client.URL = "http://www.company.com:9090/msh";

EBData data = new EBData();
data.EDIType = "application/edi-x12";
data.Filename = "C:\\files\\myfile.x12";
data.Name = "myfile.x12";

client.EDIData.Add(data);

//Send file(s) and verify the receipt.
client.SendFiles();

Asynchronous Receipts

The component also supports asynchronous receipts. In this configuration a file is sent from the component to another party, but the receipt is not returned in the response. Instead, the other party sends the receipt at a later time. The AS4Server component may be used inside a web page to receive the asynchronous receipt. After receiving the receipt either AS4Server or AS4Client may be used to verify the receipt.

Details about the original message must be stored so that the receipt can be correlated with the message and properly verified. The easiest way to do this is to set AsyncReceiptInfoDir before calling SendFiles. The component will automatically store the required information.

See the VerifyReceipt method of AS4Server for details about verifying asynchronous receipts.

To indicate that an asynchronous receipt is expected set ReceiptReplyMode to rrmAsync. The following properties are applicable when calling this method with an agreement specifying a synchronous receipt (a receipt provided in the response):

  • AgreementRef
  • AS4From
  • AS4To
  • AsyncReceiptInfoDir
  • EDIData
  • URL
  • RecipientCerts (required to encrypt)
  • SignerCert (required to verify signed receipts)
  • SigningCert (required to sign files)
  • ConversationId (optional)
  • EncryptionAlgorithm (optional)
  • LogDirectory (optional)
  • MessageId (optional)
  • MessageProperties (optional)
  • OriginalSOAPMessage (optional)
  • OriginalSOAPMessageId (optional)
  • Profile (optional)
  • ReceiptReplyMode
  • Service (optional)
  • ServiceType (optional)
  • SignatureAlgorithm (optional)

SendFiles Example (asynchronous receipt):

client.Profile = As4clientProfiles.ebpfENTSOG;

//Specify the agreement and party information
client.AgreementRef = "http://agreements.company.com/sign_and_encrypt_async";

client.AS4From.Role = "Sender";
client.AS4From.Id = "org:b2b:example:company:A";

client.AS4To.Role = "Receiver";
client.AS4To.Id = "org:b2b:example:company:B";
      
//Configure the component to expect a synchronous receipt.      
client.ReceiptReplyMode = As4clientReceiptReplyModes.rrmAsync;

client.AsyncReceiptInfoDir = "C:\\async_info";

//Company A's private certificate. Used to sign the outgoing message and files.
client.SigningCert = new Certificate(CertStoreTypes.cstPFXFile, "C:\\files\\CompanyA.pfx", 
    "password", "*");

//Company B's public certificate. Used to encrypt the outgoing files.
client.RecipientCerts.Add(new Certificate("C:\\files\\as4\\CompanyB.cer"));

//Company B's public certificate. Used to verify the signed receipt.
client.SignerCert = new Certificate("C:\\files\\as4\\CompanyB.cer");

client.URL = "http://www.company.com:9090/msh";

EBData data = new EBData();
data.EDIType = "application/edi-x12";
data.Filename = "C:\\files\\myfile.x12";
data.Name = "myfile.x12";

client.EDIData.Add(data);

//Send file(s).
client.SendFiles();

At this point the file(s) have been sent, but a receipt has not yet been received. AS4Server can be used within a web site to listen for the receipt.

//**** Inside a web site ****
As4server server = new As4server;
server.ReadRequest();

if (!String.IsNullOrEmpty(server.IncomingReceipt.Content))
{
  server.AsyncReceiptInfoDir = "C:\\async_info";
  server.VerifyReceipt();
  //The receipt is now verified
}

AS4Client: Receiving Files

The ReceiveFiles method establishes a connection to the server specified by URL and receives files.

The MPC property specifies the Message Partition Channel from which messages will be received. The server will reply with files from this channel. If IncomingDirectory is set before calling this method the files will be written to the specified folder, otherwise inspect EDIData to obtain the received file data. The following properties are applicable when calling this method:

  • SigningCert (required to sign the request)
  • Certificate (required for decryption)
  • SignerCert (required for signature verification)
  • URL
  • IncomingDirectory (optional)
  • LogDirectory
  • MPC
  • TokenUser
  • TokenPassword
  • TokenPasswordType

After calling this method the following properties will be populated and may be inspected:

  • AS4From
  • AS4To
  • AgreementRef
  • ConversationId
  • Service
  • ServiceAction
  • ServiceType
  • MessageId
  • Receipt

The Receipt property will be populated with the receipt corresponding to the received message, but it is not yet delivered. The receipt may be delivered by bundling it with another request to receive files, or by calling SendReceipt.

To bundle the receipt with a subsequent ReceiveFiles call, the Receipt property must hold the receipt. If the same instance of the component is being used this is already true since Receipt is populated automatically after receiving the file. To use another instance of the component for multiple calls to ReceiveFiles be sure to save the Receipt's ReceiptContent and ReceiptRefToMessageId values for later use.

ReceiveFiles Example:

client.Profile = As4clientProfiles.ebpfENTSOG;

//Company A's private certificate. Used for signing the request.
client.SigningCert = new Certificate(CertStoreTypes.cstPFXFile, "C:\\files\\as4\\CompanyA.pfx", 
    "password", "*");

//Company A's private certificate. Used for decrypting the file.
client.Certificate = new Certificate(CertStoreTypes.cstPFXFile, "C:\\files\\as4\\CompanyA.pfx", 
    "password", "*");

//Company B's public certificate. Used for signature verification.
client.SignerCert = new Certificate("C:\\files\\as4\\CompanyB.cer");

client.URL = "http://www.company.com:9090/msh";

//Message Channel id
client.MPC = "http://example.company.com/mpc/test";

client.IncomingDirectory = "C:\\incoming_dir";
client.ReceiveFiles();

//Inspect client.AgreementRef and other properties for information about the received files
Console.WriteLine(client.AgreementRef);
Console.WriteLine(client.AS4From.Id);
Console.WriteLine(client.AS4To.Id);
Console.WriteLine(client.ConversationId);

//Save the receipt for later use

string receiptContent = client.Receipt.Content;
string receiptRefId = client.Receipt.RefToMessageId;

At this stage the receipt data is saved. Later, when making another call to ReceiveFiles, populate the Receipt property with this receipt data. When ReceiveFiles is called again, the receipt for the previous message will be included with the request.

client.Receipt = new EBReceipt(receiptRefId, receiptContent);
client.ReceiveFiles(); //This will now include the bundled receipt

AS4Server: Reading the Request

To begin, when a request is received first call ReadRequest. This reads the AS4 request from the current HttpContext. Alternatively the request data may be passed directly to the component by calling SetRequestStream. After calling ReadRequest the following properties may be checked:

  • AgreementRef
  • AS4From
  • AS4To
  • ConversationId
  • EDIData
  • Errors
  • IncomingReceipt
  • MessageId
  • MessageProperties
  • MPC
  • Service
  • ServiceAction
  • ServiceType

The first step after calling ReadRequest is to determine if the client is sending files (push) or requesting files (pull). To determine this check the value of AgreementRef and MPC. For instance:

if (server.AgreementRef == "" && server.MPC != "")
{
  //The client is requesting files from the specified MPC
  //No other relevant properties are populated
}
else //AgreementRef is not empty, and MPC is empty
{
  //The client is sending files. AgreementRef is populated with the agreement reference.
  //AS4From, AS4To, ConversationId, etc are populated
}

Determining if the request contains an asynchronous receipt from a previous transmission may also be done at this time by checking the IncomingReceipt property. If it is populated a receipt is present. To verify the receipt set AsyncReceiptInfoDir to the directory where information about the message was originally stored and call VerifyReceipt. If the receipt is signed SignerCert must also be set. See the section below and also for more details.

Once information about the request is determined the component may then be configured to respond appropriately depending on the operation.

AS4Server: Receiving Files

When receiving files first check the AgreementRef, AS4From, and AS4To properties to determine who is sending the files and with what previously agreed upon configuration. Once this is known, if the request is signed and encrypted set Certificate to the decryption certificate and SignerCert to the public certificate used for signature verification. IncomingDirectory may optionally be set to automatically store the incoming files.

Receiving Files Example (synchronous receipt):

//Process incoming files and send a signed receipt

server.ReadRequest();

//Inspect values from the request in order to load appropriate certificates etc.
//Console.WriteLine(server.AgreementRef);
//Console.WriteLine(server.AS4From.Id);
//Console.WriteLine(server.AS4To.Id);)

server.IncomingDirectory = "..\\MyFiles";
 
//Our private certificate. Used to decrypt the incoming file
server.Certificate = new Certificate(CertStoreTypes.cstPFXFile, 
    Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyB.pfx"), "password", "*");

//Partner's public certificate. Used to verify the signature on the incoming message and files.
server.SignerCert = new Certificate(Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyA.cer"));

server.ParseRequest();

server.ReceiptReplyMode = As4serverReceiptReplyModes.rrmSync;

//Our private certificate. Used to sign the receipt.
server.SigningCert = new Certificate(CertStoreTypes.cstPFXFile,     
    Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyB.pfx"), "password", "*");

server.SendResponse(); //Sends the receipt

Receipts may be sent in the response (synchronous) or at a later time (asynchronous). If the agreement specifies that the receipt be sent asynchronously the following steps may be taken to send the receipt.

After calling ReadRequest the ReceiptReplyMode may be set to indicate the receipt will be returned asynchronously. After calling ParseRequest call SendAckResponse to send back a HTTP 200 OK to the client. The receipt may then be returned later.

To send an asynchronous receipt AS4Client may be used. This can be sent to the partner's web site, or bundled with a later response (depending on the agreement made between the parties). In the example below AS4Client is used to send the receipt to the other party's web site.

Receiving Files Examples (asynchronous receipt):

//Process incoming files and send an asynchronous receipt

server.ReadRequest();

//Inspect values from the request in order to load appropriate certificates etc.
//Console.WriteLine(server.AgreementRef);
//Console.WriteLine(server.AS4From.Id);
//Console.WriteLine(server.AS4To.Id);)

server.IncomingDirectory = "..\\MyFiles";
 
//Our private certificate. Used to decrypt the incoming file
server.Certificate = new Certificate(CertStoreTypes.cstPFXFile, 
    Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyB.pfx"), "password", "*");

//Partner's public certificate. Used to verify the signature on the incoming message and files.
server.SignerCert = new Certificate(Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyA.cer"));

server.ParseRequest();

server.ReceiptReplyMode = As4serverReceiptReplyModes.rrmAsync;

//Our private certificate. Used to sign the receipt.
server.SigningCert = new Certificate(CertStoreTypes.cstPFXFile,
    Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyB.pfx"), "password", "*");

server.SendAckResponse(); //Sends an ack, but not the receipt

At this point Receipt is populated with the receipt to be sent. Store the Receipt's ReceiptContent and ReceiptRefToMessageId values for use when sending the receipt later. Sending a receipt can be done with AS4Client.

Sending an Asynchronous Receipt Example:

//Send an asynchronous receipt
client.URL = "http://www.company.com:9090/msh";
client.Receipt = new EBReceipt(server.Receipt.RefToMessageId, server.Receipt.Content);
client.ReceiptReplyMode = As4clientReceiptReplyModes.rrmAsync;
client.SendReceipt();

AS4Server: Sending Files

To process a request to send files first check the MPC property. This holds the Message Partition Channel (MPC) from which the client would like to receive files. Next, set AgreementRef, AS4From, and AS4To. Check IncomingReceipt to determine if the request has a bundled receipt. If it does VerifyReceipt can be called to verify the receipt.

If the client makes use of UsernameToken authentication the TokenAuthentication event will fire when processing the request.

To send files back to the client simply set EDIData to the files you wish to send. When SendResponse is called the files will be sent back to the client.

Send Files Example:

//Process a request to send files (pull)

//Holds information from the original send so that receipts can be verified later
server.AsyncReceiptInfoDir = Path.Combine(Request.PhysicalApplicationPath, 
    "..\\temp\\ReceiptInfoDir");

server.Profile = As4serverProfiles.ebpfENTSOG;
server.ReadRequest();

//The receipt may be signed depending upon the AgreementRef
server.SignerCert = new Certificate(Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyA.cer"));

//If the request has a bundled receipt verify it first
if (!string.IsNullOrEmpty(server.IncomingReceipt.Content))
{
  server.VerifyReceipt();
}

//If the request is a pull request (MPC is set)
if (server.AgreementRef == "" && server.MPC != "")
{
  server.AgreementRef = "http://agreements.company.com/pull_files";
  server.AS4From.Id = "org:holodeckb2b:example:company:B";
  server.AS4From.Role = "Sender";

  server.AS4To.Id = "org:holodeckb2b:example:company:A";
  server.AS4To.Role = "Receiver";

  server.ReceiptReplyMode = As4serverReceiptReplyModes.rrmAsync;

  //Our private certificate. Used to sign the message and files.
  server.SigningCert = new Certificate(CertStoreTypes.cstPFXFile, Path.Combine(Request.PhysicalApplicationPath, "..\\files\\CompanyB.pfx"), 
    "password", "*");

  //Partner's public certificate. Used to encrypt files. 
  server.RecipientCerts.Add(new Certificate(Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyA.cer")));

  EBData data = new EBData();
  data.EDIType = "text/xml";
  data.Data = "<test>Hello AS4 World!</test>";
  server.EDIData.Add(data);

  server.SendResponse();
}

AS4Server: Processing Asynchronous Receipts

Any incoming request may potentially include a receipt. The request may be a receipt by itself, or it may be bundled with another type of request (send/receive). When initially sending files AsyncReceiptInfoDir may be set to store data about the original message on disk for use when verifying the receipt. If this is not desired, manually store the OriginalSOAPMessage and OriginalSOAPMessageId instead.

To detect if an incoming request contains a receipt simply check the IncomingReceipt property's ReceiptContent field. If it is populated, the request includes a receipt. Set AsyncReceiptInfoDir to the same location as when the file was originally sent. Or alternatively set OriginalSOAPMessage and OriginalSOAPMessageId properties to the original values.

If the receipt is signed set SignerCert to the public certificate which will be used to verify the signature. Lastly call VerifyReceipt. This will perform any signature verification and verify the receipt content as well, matching it to the original message values.

Processing Asynchronous Receipts Example:

server.ReadRequest();

//The receipt may be signed depending upon the AgreementRef
server.SignerCert = new Certificate(Path.Combine(Request.PhysicalApplicationPath, 
    "..\\files\\CompanyA.cer"));

//If the request contains a receipt verify it
if (!string.IsNullOrEmpty(server.IncomingReceipt.Content))
{
  server.VerifyReceipt();
}

We appreciate your feedback.  If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.