Kurt Huffman

Accessing the LogicMonitor REST API with Postman and LMv1 API Token Authentication

Recommended Posts

Introduction

Postman is widely used for interacting with various REST APIs such as LogicMonitor's. However, there is no out-of-the-box support for the LMv1 authentication method which we recommend as a best practice. This document describes how to configure Postman to use LMv1 authentication when interacting with our REST API.

Overview

Postman's pre-request script functionality provides the ability to generate the necessary Authorization header for LMv1 authentication. As the name suggests, the pre-request script runs immediately before the request is made to the API endpoint. We set the pre-request script at the collection level in Postman so that it will run automatically for every request that is part of the collection.

The script requires three input parameters: a LogicMonitor API token (or ID), its associated key, and the full request URL. These parameters are made available to the script by creating a Postman environment and setting the values as environment variables. If you need to access multiple LogicMonitor accounts (portals), create a separate environment for each to store the applicable API and URL information. Since all API requests to a given account use the same base URL (https://<account>.logicmonitor.com/santaba/rest) it is convenient to store this as an environment variable.

The output of the script is the value of the Authorization header. The script writes the header value to an environment variable which is then inserted as the Authorization header value in the request.

Instructions

  1. 1. Download and install Postman.
     
  2. 2. Launch Postman and create a new collection that will be used for all LogicMonitor API requests.
     
  3. 3. In the create collection dialog, select the "Pre-request Scripts" section and paste in the following code.
// Get API credentials from environment variables
var api_id = pm.environment.get('api_id');
var api_key = pm.environment.get('api_key');
  
 // Get the HTTP method from the request
var http_verb = request.method;
// Extract the resource path from the request URL
var resource_path = request.url.replace(/(^{{url}})([^\?]+)(\?.*)?/, '$2');
// Get the current time in epoch format
var epoch = (new Date()).getTime();

// If the request includes a payload, included it in the request variables
var request_vars = (http_verb == 'GET'||http_verb == 'DELETE') ?
http_verb + epoch + resource_path : http_verb + epoch + request.data + resource_path;
  
 // Generate the signature and build the Auth header
var signature = btoa(CryptoJS.HmacSHA256(request_vars,api_key).toString());
var auth = "LMv1 " + api_id + ":" + signature + ":" + epoch;

// Write the Auth header to the environment variable
pm.environment.set('auth', auth);

 

4. Create a new environment. Create the environment variables shown below. You do not need to provide a value for the "auth" variable since this will be set by the pre-request script. Be sure to use the api_id, api_key, and url values appropriate for your LogicMonitor account.

postman_manage_enviroment.png.22308ab1f541cb4e67638269f16af79f.png

5. Create a request and add it to the collection with the pre-request script. A sample request is shown below with the necessary parameters configured.

      1.      1. Set the environment for the request,
      2.      2. Set the HTTP method for the request.
      3.      3. Use {{url}} to pull the base URL from the environment variable. Add the resource path and any request parameters your API request may require.
      4.      4. Add the Authorization header and set the value to {{auth}} to pull the the value from the environment variable.
      5.      5. POST, PUT, and PATCH requests only: if your request includes JSON data, be sure to select the Body tab and add it.

postman_request.png.99c498cad6947e23d15b27032aa5badd.png

 

6. Press Send to send the request. The response will appear below the request in Postman.

postman_response.png.34f41380ab54db71c39970488f12bd17.png

 

Troubleshooting

You receive the response "HTTP Status 401 - Unauthorized"

Confirm the following:

     • The proper environment has been specified for the request.
     • The necessary environment variables have been set and their values are correct. Note that the script relies on the specific variable names used in this document: "api_id", "api_key", "url", and "auth".
     • The request is a member of the collection configured with the pre-request script.

Postman reports "Could not get any response" or "There was an error in evaluating the Pre-request Script:  TypeError: Cannot read property 'sigBytes' of undefined"

Make sure you have set the proper environment for the request and all necessary environment variables and values are present.

 
 
 
Edited by Kurt Huffman
add tag

Share this post


Link to post
Share on other sites

Is it possible to use other rest api motors like Restlet client (add in to chrome) and perform a clean request. in Postman You have a pre-request script in your environment for every request. WHy I'm wondering is that I want to Use Power BI to collect data from LM toll gather information from different system to show an central space for all systems we have.

Share this post


Link to post
Share on other sites

LMv1 (token-based) authentication relies on a dynamically generated signature in the Authorization header. Current time is one of the inputs for generating the signature which is why the pre-request script must be run for each request.

While we recommend using LMv1 authentication due to its greater security, basic authentication (user-password) is supported for v1 of our API and is easily implemented when dynamic generation of the Authorization header is not possible. You can find more information about authenticating with our API here: Using LogicMonitor's REST API

Share this post


Link to post
Share on other sites

If GET works but POST does not, there may be something wrong with the request variables in the script. Make sure the code in your script generating the request variables (request_vars) matches the code in the example.

You can add a line to the relevant section of the script to inspect the request variables in the Postman console:

// If the request includes a payload, included it in the request variables
var request_vars = (http_verb == 'GET'||http_verb == 'DELETE') ? 
http_verb + epoch + resource_path : http_verb + epoch + request.data + resource_path;
console.log(request_vars)

After saving the change to the pre-request script, open the Postman console then send the request.

request_vars for a GET request is just GET+timestamp+resource_path like this:

GET1553268441890/device/groups

request_vars for a POST request must include the body data between the timestamp and the resource path and so should look like this:

POST1553267947762{"name":"Postman"}/device/groups

I hope this helps. If not, feel free to share your POST request and I'll be happy to take a look.

Share this post


Link to post
Share on other sites

Ok I am getting "POST1553787894612[object Object]/sdt/sdts"

Here is my script:

// Get API credentials from environment variables
var api_id = pm.environment.get('api_id');
var api_key = pm.environment.get('api_key');
  
 // Get the HTTP method from the request
var http_verb = request.method;
// Extract the resource path from the request URL
var resource_path = request.url.replace(/(^{{url}})([^\?]+)(\?.*)?/, '$2');
// Get the current time in epoch format
var epoch = (new Date()).getTime();

// If the request includes a payload, included it in the request variables
var request_vars = (http_verb == 'GET'||http_verb == 'DELETE') ?
http_verb + epoch + resource_path : http_verb + epoch + request.data + resource_path;
console.log(request_vars)
  
 // Generate the signature and build the Auth header
var signature = btoa(CryptoJS.HmacSHA256(request_vars,api_key).toString());
var auth = "LMv1 " + api_id + ":" + signature + ":" + epoch;

// Write the Auth header to the environment variable
pm.environment.set('auth', auth);

image.png.61003d3ebfd17846b47786acd34c7f6c.png

 

Here is the post: {{url}}/sdt/sdts?type=DeviceGroupSDT&deviceGroupFullPath=Test&sdtType=1&startDateTime=1553400000000&endDateTime=1553425200000&dataSourceName=Ping

Edited by Jason Miller
Add Post call

Share this post


Link to post
Share on other sites

Thanks for sharing. Your pre-request script looks good. But "[object Object]" in the request variables suggests that there is no data in the body of your request. POST requests require some body data, most often in JSON format.

Here is example data for a POST to /sdt/sdts taken from https://www.logicmonitor.com/support/rest-api-developers-guide/v1/sdts/add-sdts/:

{"sdtType":1,"type":"ServiceSDT","serviceId":47,"startDateTime":1469134752000,"endDateTime":1469144995000}

In Postman, it would look like this:

postman_body.png.d94e65052f603e36b4b3982ed1a7d4da.png

Confirm that your request contains properly formatted JSON data in the body. If it does, and you're still getting this error, I'll be happy to take a closer look.

Share this post


Link to post
Share on other sites

I'm trying to make a simple GET request ( /device/devices )  and I've successfully created my API access id in Logic Monitor user settings, but I don't see where I can obtain the KEY.   Some documentation I found online seems to indicate I have to generate the key based on a base64 of a generated hash (HMAC256), while this thread seems to indicate(?) that the KEY is assigned along with the access ID.   Can you please elaborate on how one goes about obtaining the KEY to use for the POSTMAN pre request script?  

Share this post


Link to post
Share on other sites

Yeah, when you generated the API id, it would have actually generated the ID along with the key. If you didn't write down the key somewhere, you'll need to destroy and recreate one. The access id and key are both generated as soon as you pick the user that the pair will belong to.  After you hit the save button, you will never again be able to retrieve the access key from LM, hence the copy buttons.  The id is clearly visible after saving, but not they key.

image.png.eaa095a36858a8f7195b4dd42885d274.png

Share this post


Link to post
Share on other sites

Awesome, thanks.  I completely overlooked that.  Getting results now and very appreciative of your help!

Share this post


Link to post
Share on other sites

Another question regarding the REST API.  I've had much success using a TEST API ID and KEY created under my own account / email address.  I can make the necessary GET requests and obtain the JSON response for all the devices that I can see within Logic Monitor.

There are OTHER devices / resources that fall outside what my individual account has access to and I've had our security / infrastructure team setup a logic monitor user account that has READ ONLY access to the other devices / resources.  However when I login with that account and try to create a new API ID and Access Key, I don't see the ability to create a new one (there's no PLUS icon / symbol that I used before to create the initial / test  key & ID)

Which leads me to the question:  Is this due to the fact that API access allows POSTs to perform actions through the REST API so therefore READ ONLY will NOT be able to have access to the API endpoints? (i.e. a READ ONLY user account lacks the necessary permissions to have access to the API?)

Thanks for any light someone can share on this.  Hopefully there's a way for my read only account to make API calls and get data, but something tells me it's a permissions / access rights issue where READ ONLY needs to be opened up to have WRITE permissions as well.

Thanks for any light someone can shed on this for us.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.