"Proxy-Authorization" is removed at the destination server - node.js

i use request module to consume web services. the web services expect Proxy-Authorization field in the header.
i send this value, but in the destination server, Proxy-Authorization is gone.
please help.

I got some helps from my colleage, here is the way to work-around.
just override proxyHeaderExclusiveList
const proxyHeaderExclusiveList = [];
proxyHeaderExclusiveList.concat = function newConcat() {
return this;
};
const options = {
url: SOME_URL,
headers: SOME_HEADERS,
proxyHeaderExclusiveList: proxyHeaderExclusiveList
};

Related

How to use the full request URL in AWS Lambda to execute logic only on certain pages

I have a website running on www.mywebsite.com. The files are hosted in an S3 bucket in combination with cloudFront. Recently, I have added a new part to the site, which is supposed to be only for private access, so I wanted to put some form of protection on there. The rest of the site, however, should remain public. My goal is for the site to be accessible for everyone, but as soon as someone gets to the new part, they should not see any source files, and be prompted for a username/password combination.
The URL of the new part would be for example www.mywebsite.com/private/index.html ,...
I found that an AWS Lambda function (with node.js) is good for this, and it kind of works. I have managed to authenticate everything in the entire website, but I can't figure out how to get it to work on only the pages that contain for example '/private/*' in the full URL name. The lambda function I wrote looks like this:
'use strict';
exports.handler = (event, context, callback) => {
// Get request and request headers
const request = event.Records[0].cf.request;
const headers = request.headers;
if (!request.uri.toLowerCase().indexOf("/private/") > -1) {
// Continue request processing if authentication passed
callback(null, request);
return;
}
// Configure authentication
const authUser = 'USER';
const authPass = 'PASS';
// Construct the Basic Auth string
const authString = 'Basic ' + new Buffer(authUser + ':' + authPass).toString('base64');
// Require Basic authentication
if (typeof headers.authorization == 'undefined' || headers.authorization[0].value != authString) {
const body = 'Unauthorized';
const response = {
status: '401',
statusDescription: 'Unauthorized',
body: body,
headers: {
'www-authenticate': [{key: 'WWW-Authenticate', value:'Basic'}]
},
};
callback(null, response);
}
// Continue request processing if authentication passed
callback(null, request);
};
The part that doesn't work is the following part:
if (!request.uri.toLowerCase().indexOf("/private/") > -1) {
// Continue request processing if authentication passed
callback(null, request);
return;
}
My guess is that the request.uri does not contain what I expected it to contain, but I can't seem to figure out what does contain what I need.
My guess is that the request.uri does not contain what I expected it to contain, but I can't seem to figure out what does contain what I need.
If you're using a Lambda#Edge function (appears you are). Then you can view the Request Event structure here: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-event-structure.html#lambda-event-structure-request
You can see the actual value of the request URI field by using console.log and checking the respective logs in Cloudwatch.
The problem might be this line:
if (!request.uri.toLowerCase().indexOf("/private/") > -1) {
If you're strictly looking to check if a JavaScript string contains another string in it, you probably want to do this instead:
if (!request.uri.toLowerCase().indexOf("/private/") !== -1) {
Or better yet, using more modern JS:
if (!request.uri.toLowerCase().includes("/private/")) {

How to add custom headers in getDocument() request of pdfjs

Trying to add custom headers to the pdfjs getDocument request.
Based on the GitHub suggestion have tried to add it.
Even while Debugging it is being shown but I am not sure why it is not working.
Below is my js code
var parameter = {
url: this.url,
httpHeaders: { Authorization: `password` },
withCredentials: true,
}
var loadingTask = pdfjsLib.getDocument(parameters);
This is my chrome network request
I believe the problem is happening, because you've defined the Authorization Header wrongly. Instead of putting the password, you must define the Authorization Type you are using. For instance, suppose you are using Basic Authorization, so the Authorization Header should be:
{
Authorization: 'BASIC <BASE64 ENCODED OF USERNAME:PASSWORD>'
}
If you are using it correctly, try to verify if your version (PDFJS) has already the patch which has fixed the problem. Just go to pdf.worker.js and verify the object NetworkManager. Verify if it has the httpHeaders and withCredentials properties defined. Something like this:
function NetworkManager(url, args) {
this.url = url;
args = args || {};
this.isHttp = /^https?:/i.test(url);
this.httpHeaders = (this.isHttp && args.httpHeaders) || {};
this.withCredentials = args.withCredentials || false;
...
}

Are multiple HTTP headers with the same name supported?

I'm experimenting with migrating an ASP.net REST backend to Azure Functions. My possibly naive approach to this was creating a catch-all function that proxies HTTP requests via Node's http module, then slowly replacing endpoints with native Azure Functions with more specific routes. I'm using the CLI, and created a Node function like so:
var http = require("http")
module.exports = function (context, req) {
var body = new Buffer([])
var headers = req.headers
headers["host"] = "my.proxy.target"
var proxy = http.request({
hostname: "my.proxy.target",
port: 80,
method: req.method,
path: req.originalUrl,
headers: headers
}, function(outboundRes) {
console.log("Got response")
context.res.status(outboundRes.statusCode)
for(header in outboundRes.headers) {
console.log("Header", header)
if(header != "set-cookie")
context.res.setHeader(header, outboundRes.headers[header])
else
console.log(outboundRes.headers[header])
}
outboundRes.addListener("data", function(chunk) {
body = Buffer.concat([body, chunk])
})
outboundRes.addListener("end", function() {
console.log("End", context.res)
context.res.raw(body)
})
})
proxy.end(req.body)
}
This almost seems to work, but my backend sets several cookies using several Set-Cookie headers. Node hands these back as an array of cookie values, but it seems like Azure Functions doesn't accept arrays as values, or doesn't permit setting multiple headers with the same name, as seems to be allowed for Set-Cookie.
Is this supported? I've googled and have checked out the TypeScript source for Response, but it doesn't appear to be.
If this isn't supported, what Azure platform services should I use to fail over 404s from one app to another, so I can slowly replace the monolith with Functions? Function proxies would work if I could use them as fallbacks, but that doesn't appear possible.
Thanks!

NTLM Proxy Authentication in Node Request

I'm trying to make a request using Node behind a corporate web proxy which requires NTLM authentication. I've tried using a couple libraries such as the proxying-agent but am having little success.
Here's a simplified version of my code using the request library and ntlm.js similar to the proxying-agent. I'd expect to receive a successful response after the last request call but for some reason am still getting a 407 -
var ntlmRequest = function(req) {
var ntlmOptions = {};
ntlmOptions.ntlm = {};
ntlmOptions.method = 'GET';
ntlmOptions.path = 'http://www.jsonip.co.uk';
ntlmOptions.ntlm.username = 'USERNAME';
ntlmOptions.ntlm.password = 'Pa$$word';
ntlmOptions.ntlm.workstation = 'PC-NAME';
ntlmOptions.ntlm.domain = 'DOMAIN';
var type1message = ntlm.createType1Message(ntlmOptions.ntlm);
var requestOptions = {
url: 'http://www.jsonip.co.uk',
proxy: 'http://webproxy.domain.com:8080',
headers: req.headers
};
requestOptions.headers['Proxy-Authorization'] = type1message;
requestOptions.headers['Proxy-Connection'] = 'Keep-Alive'
request(requestOptions, function(err,res){
var type2message = ntlm.parseType2Message(res.headers['proxy-authenticate']);
var type3message = ntlm.createType3Message(type2message, ntlmOptions.ntlm);
requestOptions.headers['Proxy-Authorization'] = type3message;
request(requestOptions, function(err,res){
console.log(res.statusCode);
});
});
};
I've tried comparing some packet captures and on a working NTLM request (using curl) I can see this during the type 1 and type 3 requests -
[HTTP request 1/2]
[HTTP request 2/2]
My requests only show 1/1.
I'm thinking maybe in other implementations of NTLM the browsers are spanning the requests across multiple packets. Not sure if this is the reason why it isn't working, or maybe just a different way of doing things.
Thanks in advance.

How to get body content from request in mobile service in Azure

I crate a mobile service and also a custom api for that in Azure. I use fiddler to send request and do some basic and simple testing.
At Azure side, I create a custom api for my mobile service. Let say the name is ExampleCustomApi. And in the code I have
exports.put = function(request, response) {
var tags = request.parameters.tags;
...
...
}
At fiddler side, I set http method to "PUT" and the url to my custom api.
Then I set a request body to { "tags": "tag1" }.
When I execute the request in fiddler, I receive 500 back. The log in Azure's mobile service says that parameters is undefined.
My question, then, is how to get the request body at the server side. I look at the document of request object, it seems to me that parameters is the one I should use, but it doesn't work.
request is an object in express.js library.
This is the documentation from MSDN http://msdn.microsoft.com/library/azure/jj554218.aspx
the documentation from express.js http://expressjs.com/api.html#req.body
And I can use request.body to get the body content.
After many attempts we cracked getting the content from a weburl. Hope this helps :) Jsonbody would hold your page content. This is a copy where we pulled json from one of our API's
var message = "try";
var jsonBody = "";
var request = require('request');
request.get({
url: "https://superduperwebaddress.com/api/pull"},
function(error,response,body){
if(!error)
{
var mybody = JSON.parse(body);
jsonBody = mybody;
console.warn("we are here well");
}else{
console.error(error);
}
}
);

Resources