Search code examples
node.jsrestauthenticationntlm

NTLM Api access with Node.js


Full disclaimer: I have never worked with Microsofts NTLM before.

I've tried around 30 different ways to access the 7Pace timetracker API on our local TFS instance. I know it works if i access the URI directly in Chrome, it prompts me for my AD login, and swiftly serves me all the data requested. Same for Postman, except there is an authentication tab for NTLM ahead of time.

Postman suggests this for Node.js using request:

var request = require("request");

var options = {
 method: 'GET',
 url: 'http://TFSURL/odata/TimeExport%28StartDate=%272018-11-14%27,EndDate=%272018-11-14%27%20,PopulateTopParentColumns=null,GroupTimeByDateByUser=null,IncludeBillable=null%29',
headers: {
 'cache-control': 'no-cache',
  Authorization: 'NTLM NOTTHEREALTOKENKJASDKLHWKLLASBEDBSDAOBAW' 
 }
};

request(options, function (error, response, body) {
  if (error) throw new Error(error);
  console.log(body);
});

This returns nothing. Notice the Authorization header. I've tested multiple different variants of similar. My next guess was to request through Chrome, then sniff it with Tellerik Fiddler and try to replicate the headers. I've done this as well, but to no avail. I end up with a very similar result to that above, except chrome uses negotiate: enter image description here enter image description here

Any ideas on how to go about this ? Maybe other debugging options?


Solution

  • You will need to through the 3 steps of authentication for NTLM. It's not that easy if you want to do it manually as the NTLM spec is not really open.

    There's Node.js module you can use: https://www.npmjs.com/package/httpntlm (disclaimer: I created it)

    To GET your url, you would need the following:

    var httpntlm = require('httpntlm');
     
    httpntlm.get({
        url: "http://tfs2:8090/api/someclient/odata/TimeExport%28StartDate=%272018-11-14%27,EndDate=%272018-11-14%27%20,PopulateTopParentColumns=null,GroupTimeByDateByUser=null,IncludeBillable=null%29",
        username: 'your username',
        password: 'your password',
        workstation: 'anything',
        domain: ''
    }, function (err, res){
        if(err) return err;
     
        console.log(res.headers);
        console.log(res.body);
    });