NTLM Api access with Node.js - 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:
Any ideas on how to go about this ? Maybe other debugging options?

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/FlexPOS%20APS/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);
});

Related

Node.js Post Login Request stuck for Activision site

i want to login to activision site and after i convert a xsrf token via the 'get' request for the login site, when i try to make a 'post' login with my account details & the xsrfToken i'm getting stuck in the air and nothing pop up to my console and its seems like the program stil running...
This may be because they have "I'm not a robot" [recaptcha] authentication?
I took the code from : https://documenter.getpostman.com/view/5519582/SzzgAefq
var axios = require('axios');
var qs = require('qs');
var data = qs.stringify({
'username': 'myUserName',
'password': 'myPassword',
'remember_me': 'true',
'_csrf': 'xsrfToken'
});
var config = {
method: 'post',
url: 'https://s.activision.com/do_login?new_SiteId=activision',
headers: {
'Cookie': "XSRF-TOKEN=xsrfToken"
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Okay, so after checking the code, the source of the problem was what I suspected and is because of the verification of "I'm not a robot" [recaptcha] authentication!
Whoever else encounters this problem - what you need to do is generate a script that will connect from your PC browser to their site from a user for whom you manually activated the "Remember me", or you have to pay to a third-party library that will pass the verification for you. Then retrieve the session data from it.

I get an authentication code for microsoft graph, but when i try to use it, the response is InvalidAuthenticationToken

I'm trying to access onedrive through the API. I've managed to get an acces_token with files.readwrite scope. When i then try to access https://graph.microsoft.com/v1.0/me. It responds with the error "InvalidAuthenticationToken". What am i doing wrong
I've tried a bunch of different urls for example "https://graph.microsoft.com/v1.0/me/drive/root/children" and have searched stackoverflow, but nothing helped.
router.get('/response', function(req, res, next){
// already got code here.
var code = req.query.code
request.post({
url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded'},
form: {
client_id: client_id,
redirect_uri: redirect_uri,
client_secret: client_secret,
code: code,
grant_type: 'authorization_code',
},
},function(error, response, body){
if (error){
console.log(error)
}
//so far so good. The access_token from the response looks okay and the
//scope is correct as well
request.get({
url: 'https://graph.microsoft.com/v1.0/me',
headers: {
'Authorization': "Bearer " + JSON.parse(body).access_token,
},
}, function(er, re, bo) {
//this response is an error message
console.log(bo)
});
});
})
I expected to get a request with information about the onedrive, but i got an error message.
You aren't quite done yet with your authentication flow, the code you are getting back is an Authentication Code, not a Token. This is a very important distinction.
The first step in the oAuth code flow is getting the code, which you did. Then you need to 'trade' this code for an actual token. To do that you need to send another request to the server with this code and ask for your token. This request should go to a different URL. There is a lot of in depth explanation here for the flow you are using now
https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
And here for the implicit flow, if you meant to use that instead: https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-implicit-grant-flow
You might also want to look into using the AdalJS or preview MSAL.js library to handle a lot of the authentication for you, these are libraries made by Microsoft.

Session lost after redirect

I use fetch() to send a post request for logon,
after server validation, I use req.session.account = account[0]; to save the account information to the session and return a redirect URL,
But after the redirect, the account information in the session is lost, why is that?
If you would have some example code, that would help us track down the problem. My first idea would be to make sure express-session is properly configured:
var app = express();
var session = require('express-session');
app.use(session({
secret: 'ibfiyegfiyegfe' // Secret is a required option.
}));
For futher configuration options, see the express-session repository.
EDIT: Based on the additional information, I'm guessing you have express-session configured to also use cookies for managing the sessions. What this means, is that for every HTTP request Express sends a response back that includes a cookie. jQuery based AJAX calls will ignore the response cookie however, which causes consecutive requests to Express to look as if you never logged in. To allow saving the cookie when performing AJAX requests with jQuery, use the xhrFields field to enable withCredentials:
$.ajax({
url: "http://....",
type: "POST",
xhrFields: {
withCredentials: true
},
data: {username: username, password: password},
success: function(responseBody) {
console.log("success!");
},
error: function(responseBody) {
console.log("error!");
}
});
Hope this helps.
Sorry to everyone, I don't making the question clear.
I use the fetch() method send a request to logon.
fetch('/logon', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
account: account,
password: password
})
}).then(function(response){
return response.json();
}).then(function(json){
if(json.success == 1){
window.location.href = json.redirecturl;
}else{
indexDispatcher.dispatch({
actionType: 'logonFaild',
errorInfo: json.msg
});
}
});
And the server's response is just simple JSON:
if (err) {
consoloe.log(err);
} else {
req.session.account = account[0]; //save account to session
var redirecturl = '/team/' + team[0].id;
console.log("account添加到session了");
res.json({
success: 1,
redirecturl: redirecturl
});
}
But when the client get the redirecturl and redirect, the account data is lost,so it will occur a TypeError: Cannot read property 'id' of undefined(id is saved in req.session.account).
But when I use jquery $.ajax relpace fetch, it works well. I don't know the reason.
I had the same experience like you hundreds of times which I finally found the problem. You don't need to worry if cookies enable or disable.
You just have to re-declare parts of your scripts (variables-the data which you want to display) in a if else condition.
Just redeclare the same thing using !isset and then else with the same variables mentioned twice in the if else condition, if you understand what i mean.
It will call back the same variables over and over. And make sure start session is above the page. no need to worry about headers or white lines, it has actually nothing to do with it.
I've tried it a million times. You don't need to bother using ajax etc. PHP can do almost everything. cheerio.

I can't access cookie returned after http post in NodeJS

I have a simple NodeJS app which authenticates with remote Java CMS. On successful authentication the CMS returns a cookie.
However, for the life of me I can't figure how to access / get this cookie value. (I need the cookie in order to make requests to the CMS's API, once authenticated).
I get the cookie returned in a curl command ok but can't access it in NodeJS.
Curl Command:
curl -v -k --data "username=admin&password=password111&realm=cms101"
https://test.abeo.ie/gatekeeper/rs/authenticate/login
Now here is my NodeJS app's code:
//disable self-signed ssl cert rejection
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
var http = require('http');
var request = require('request');
var Cookies = require('cookies');
//enable cookies
request.defaults({jar: true});
request({
url: 'https://test.abeo.ie/gatekeeper/rs/authenticate/login', //URL to hit
qs: {username: 'admin', password: 'password111', realm: 'cms101'}, //Query string data
method: 'POST', //Specify the method
headers: { //We can define headers too
'Content-Type': 'application/x-www-form-urlencoded'
}
},
function(error, response, body){
if(error) {
console.log(error);
} else {
//response.cookie comes out as 'undefined'
console.log(response.statusCode, body, response.cookie);
}
})
So my question is: How do I read the cookie value from the response as the response.cookie value prints out as undefined.
Thanks,
Mike
** If this question seems to vague... Just say so and I will clear it up.
I think I have just answered my question :)
I had the syntax wrong and instead of
console.log(response.statusCode, body, response.cookie);
I needed
console.log(response.statusCode, body, response.headers['set-cookie']);
Just working on parsing the thing now :)

Scraping a website which requires authentication using node.js

I am trying to scrap this website https://www.erobertparker.com/entrance.aspx it requires authentication I am using request module to get authenticated like this,
request({
url:"https://www.erobertparker.com/login.aspx",
method:"POST",
form:{UNENTRY:"username",PWENTRY:"password"}
},
function(error,response,body){
})
but i am unable to get authenticated what i am doing wrong can someone please guide me I am new to web scraping world :).
It's using an asp.net session cookie. You possibly need to store all cookies in a jar and then send them back on the next request.
Hi I solved this using a jar parameter in the request:
var j = request.jar();
var request = request.defaults({ jar : j }) //it will make the session default for every request
//...
request({
url:"https://www.erobertparker.com/login.aspx",
method:"POST",
form:{UNENTRY:"username",PWENTRY:"password"}
},
function(error,response,body){
//Do your logic here or even another request like
request({
url:"<ANOTHER LINK>",
method:"GET",
}, function(error, response, body){
//Some logic
});
});
You can also check the documentation of the request module:
https://github.com/request/request#examples

Resources