REST webservice OAuth2.0 - InterFormNG2

REST webservice OAuth2.0

The Rest webservice OAuth2.0 is a way to communicate with InterFormNG2, by sending normal http/https requests. The requests are authorized by using OAuth2.0.

 

The REST webservice basic is easier to get started with, but OAuth2.0 is recommended.

    

 

The parameters in the workflow component are:

  1. Path
    Enter a path, which is unique for the tenant, e.g. invoice.
  2. Input type
    The input type that will be received, default is XML.
  3. Sample XML file
    If you are going to do conditions and/or Xpath expressions, then it is recommended to refer to an optional, sample XML file. If you click the magnifying glass, then you can select the sample XML file, that you want to use as a reference.
  4. On error workflow
    Another workflow to be called, if there is an error during processing of this workflow. This can be overwritten with another workflow.
  5. Getting an access token
    Call ServerURL/oauth/token with a basic authentication header, which contains a base64 encoded clientId and clientSecret.

And the parameters:

username: which is username/tenantId – example default/home
password: example: password
grant_type: password

The access token is returned in a json reply.

See the method “Login” in the java source below.

  1. Calling the web-service
    See the method “callWebservice” in the java source or the C# source below.

If you use https for the connection, then you have 3 options:

  1. Use an official certificate
    or
  2. Install the certificate on the machine, that calls the web service.
    or
  3. The C# program can be changed, so that all certificates can be used.
Notes

Notes: The webservice will return code 200, if the URL exists (404 if it does not), even if an error has occurred.

 

When the workflow is done the current payload of the workflow is returned to the web service caller. This can e.g. be a PDF file, that has been created with the workflow component, Create PDF document or it can e.g. be an XML file which indicates if the workflow was successful or not.

 

Relevant functions are:

  1. Set Mime-type
    You can use this workflow component to set the mime-type (content type) of the file, that is returned from the workflow.
  2. Transformation
    If you want to return a transformed XML file, then you should consider to first define a transformation template and then activate it via the workflow component, XSL transformation.

If you change the payload you might want to save the initial payload with the component, Payload to named property and later retrieve the original payload again with Named property to payload.

Demo java source

The workflow need to have "hello" setup as the path

package com.interform400.testserver;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Simple example of calling the web-service in NG2
 * @author urj
 */
public class ExampleWebservice {

    public static void main(String args[]) throws Exception {
        callWebserice();
    }

    private static void callWebserice() throws Exception {

        String token = login();

        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost post = new HttpPost("http://localhost:8086/webservice/hello");
        post.addHeader("Authorization", "Bearer " + token);

        List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
        String xml = "<xml>Hello world</xml>";
        urlParameters.add(new BasicNameValuePair("xml", xml));

        post.setEntity(new UrlEncodedFormEntity(urlParameters));

        CloseableHttpResponse response = httpClient.execute(post);

        System.out.println(response.getStatusLine().getStatusCode());
    }

    private static String login() throws Exception {

        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost post = new HttpPost("http://localhost:8086/oauth/token");

        String clientId = "interform";
        String clientSecret = "Io14oarPPnv3Bso10bagGA9Ovns2lvxt";

        String basicAuthString = clientId + ":" + clientSecret;
        String encodedCredentials = Base64.getEncoder().encodeToString(basicAuthString.getBytes());

        post.addHeader("authorization", "Basic " + encodedCredentials);

        List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
        urlParameters.add(new BasicNameValuePair("username", "default/home"));
        urlParameters.add(new BasicNameValuePair("password", "password"));
        urlParameters.add(new BasicNameValuePair("grant_type", "password"));

        post.setEntity(new UrlEncodedFormEntity(urlParameters));

        CloseableHttpResponse response = httpClient.execute(post);

        InputStream is = response.getEntity().getContent();

        ObjectMapper mapper = new ObjectMapper();
        JsonNode jsonNode = mapper.readTree(is);
        String accessToken = jsonNode.get("access_token").asText();

        return accessToken;
    }
}

Demo C# source

The workflow to be called need to have setup "cstest" as the Path for this demo source


using System;
using System.Text;
using System.Text.Json;
using System.Net.Http;
using System.Collections.Generic;

// InterFormNG2 web service client example
// Requires .NET v4.5+

namespace DotNetWs
{
    class InterFormNGWs
    {
        private static readonly string serverURL = "http://localhost:8086";
        private static readonly HttpClient client = new HttpClient();

        public static WebToken DoLogin(string username, string password)
        {
            Dictionary<string, string> values = new Dictionary<string, string>
            {
                { "grant_type", "password" },
                { "username", username },
                { "password", password }
            };

            FormUrlEncodedContent content = new FormUrlEncodedContent(values);

            client.DefaultRequestHeaders.Add("Authorization",
                "Basic " + Base64Encode("interform:Io14oarPPnv3Bso10bagGA9Ovns2lvxt"));

            HttpResponseMessage response = client.PostAsync(serverURL + "/oauth/token", content).Result;

            string responseString = response.Content.ReadAsStringAsync().Result;

            Console.WriteLine(responseString);

            WebToken token = JsonSerializer.Deserialize<WebToken>(responseString);

            return token;
        }

        public static void CallWsMultipart(string endpoint, string xmlInput, WebToken webToken)
        {
            MultipartFormDataContent content = new MultipartFormDataContent();
            content.Add(new ByteArrayContent(Encoding.UTF8.GetBytes(xmlInput)), "xml", "testxml.xml");
            content.Add(new StringContent("true"), "report");

            client.DefaultRequestHeaders.Remove("Authorization");
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + webToken.access_token);

            HttpResponseMessage response = client.PostAsync(serverURL + "/webservice/" + endpoint, content).Result;

            string responseString = response.Content.ReadAsStringAsync().Result;

            Console.WriteLine();
            Console.WriteLine("Report:");
            Console.WriteLine(responseString);
        }

        public static void CallWsUrlEncoded(string endpoint, string xmlInput, WebToken webToken)
        {
            Dictionary<string, string> values = new Dictionary<string, string>
            {
                { "xml", xmlInput },
                { "report", "true" }
            };

            FormUrlEncodedContent content = new FormUrlEncodedContent(values);

            client.DefaultRequestHeaders.Remove("Authorization");
            client.DefaultRequestHeaders.Add("Authorization", "Bearer " + webToken.access_token);

            HttpResponseMessage response = client.PostAsync(serverURL + "/webservice/" + endpoint, content).Result;

            string responseString = response.Content.ReadAsStringAsync().Result;

            Console.WriteLine();
            Console.WriteLine("Report:");
            Console.WriteLine(responseString);
        }

        private static string Base64Encode(string plainText)
        {
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            return Convert.ToBase64String(plainTextBytes);
        }

        static void Main(string[] args)
        {
            WebToken webToken = DoLogin("default", "password");
            string xmlDoc = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<root>Hello World</root>";

            CallWsMultipart("cstest", xmlDoc, webToken);     // Recommended multipart post
            CallWsUrlEncoded("cstest", xmlDoc, webToken);    // Alternative URL-encoded post
        }
    }

    public class WebToken
    {
        public string access_token { get; set; }
        public string refresh_token { get; set; }
        public int expires_in { get; set; }
    }
}

 

 


    • Related Articles

    • REST webservice basic

      The REST webservice basic is a web service that can receive http/https calls using none or basic authentication. For production REST webservice OAuth2.0 is recommended. The parameters of this workflow input type are: Path The url this will be called, ...
    • REST webservice basic example

      Below a simple setup is done to illustrate how the REST webservice basic can be setup. The example below can be run without any programming at all. First a simple template to prove, that the workflow has worked and returned a PDF: The template is ...
    • Forward webservice

      When a workflow has been initiated by a webservice input component, the component Forward webservice can be used to forward the request to another URL. This is currently only implemented together with the input type, REST webservice basic, where the ...
    • Call external HTTP(s) rest apis

      In InterFormNG2 it is possible to call (most) external HTTP REST APIs / Webservices and form submits using workflow components. The calls are based on RFC2616 Hypertext Transfer Protocol HTTP/1.1 https://www.ietf.org/rfc/rfc2616.txt The external HTTP ...
    • Workflow input types

      The workflows of InterFormNG2 can get the input from various input types. In the workflow the input type is shown as the leftmost (green) component: The input types are all listed here: AS400 Command input Call InterFormNG2 via a command on the IBM i ...