Proxy Authentication in POCO Net C++ library - c++

I have been playing with the Poco Net library for some time, it is quite nice. Very convenient and easy to understand.
I was able to set a proxy address, and it is saying 407 Proxy authorization required, properly. I figured that
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
req.setCredentials(scheme, authInfo);
I tried values like "basic", "plaintext" in scheme, and "user:password" in authInfo. It doesn't seem to work. Google isn't helping.
Has anyone done this using Poco Net before? Or is the usage obvious and I'm not able to get it to work because of my ignorance towards proxy authentication in general? Please advice.
EDIT: After some more playing around, I think the setCredentials function is used when the remote server is expecting authentication information to login. I have not been able to find a way to do proxy authentication using Poco Net libraries. I was able to set the proxy server and port though. This is what I would have if there was just a proxy server without authentication:
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
session.setProxy("host", port);
session.sendRequest(req);
Need help.
EDIT: Based on the solution suggested by #StackedCrooked, I tried setting proxy authentication details to the request header before making the request, and in another approach found on the internet, I set proxy auth details only after making an initial request and a 407 error comes, and then making the request again. Both methods kept on giving the same 407 error. My current code looks like this:
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
session.setProxy("10.7.128.1", 8080);
req.set("Proxy-Authentication", "Basic bGVlbGE6bGVlbGExMjM=");
session.sendRequest(req);

You probably need to add the Proxy Authorization field to the HTTP headers. Poco's HTTPRequest class doesn't have a dedicated method for this. However, since it inherits the NameValueCollection class publicly you can set it like this:
req.set("Proxy-Authorization" , "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==");
Where QWxhZGRpbjpvcGVuIHNlc2FtZQ== is the base64 encoded version of "Aladdin:open sesame".
A lot of these problems become easier once you learn a little about the HTTP protocol. I am now mostly preaching to myself :)

I haven't used this myself, but have you looked at the HTTPBasicCredentials class? It wraps up the call to req.setCredentials via its authenticate method. You would end up with something along the lines of:
HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
HTTPBasicCredentials cred("user", "password");
cred.authenticate(req);

Related

OAuthlib thinks request is insecure because of reverse proxy

I have noticed that for every request, request.scheme is http. I can't find any official source why, but I have been told by my peers this is because of Cloudflare acting as reverse proxy and a tls terminator, causing my server's hosting provider to see http instead of https.
One part of my app uses the Google Classroom API, and I have configured a callback to a secure endpoint of my server. Upon attempting to fetch a token from the callback's absolute uri, oauthlib raises oauthlib.oauth2.rfc6749.errors.InsecureTransportError: (insecure_transport) OAuth 2 MUST utilize https. because it thinks the request is http and insecure. I have researched and found out I can set os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' to mitigate this issue, but I am hesitant to do so because I am unsure if that compromises security.
My thought process is to manually change the request url to https when I'm absolutely sure it is secure. Inspecting request.META to find which headers are set in the case of a reverse proxied http request, the code looks like this:
authorization_response = request.build_absolute_uri()
if (
authorization_response.startswith("http://") and
request.META["HTTP_X_FORWARDED_PROTO"] == "https" and
request.META["HTTP_ORIGIN"].startswith("https") and
json.loads(request.META["HTTP_CF_VISITOR"])['scheme'] == "https"
):
authorization_response = "https://" + authorization_response[7:]
... fetch the token passing authorization_response and etc
which seems to work.
Considering how little information I could find this online, I was wondering if this is a best practice and if there's a better way of letting oauthlib know the request is secure. Or, since my domain has HSTS preload, is this all unnecessary and I can get away with setting os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'?

How do I send an HTTP post request with headers and json data through a proxy with WinHTTP (C++)

I am attempting to send a post request like the one described in the title, but I cannot seem to find a good example of a generic piece of code. My work on my project is a bit tedious as I have never used WinHTTP, only libcurl before which is why I decided to ask here. To reiterate, the http request is a post request with specific header values and json data in the request body which is sent through a proxy to a website using winHTTP. If anyone could provide me with assistance, it would be greatly appreciated.

Question about accessing data from REST-ful resource using c++ and poco

I have succesfully retrieved the data using a java HttpURLConnection and setting request method as "GET". I would like to implement this in c++ as well (I'm using poco). The URL I am trying to access is "https://open.faceit.com/data/v4".
When I send the request I get a status code 400 (Bad Request) and the response message "400 The plain HTTP request was sent to HTTPS port". Why would using HTTP in java work, but using POCO in c++ I get this error? Should I be using HTTPSClientSession instead, and if so why was I able to use HTTP in java?
java code that gives return code 200
URL url = new URL(dataURL);
HttpURLConnection hc = (HttpURLConnection) url.openConnection();
hc.setRequestMethod("GET");
hc.setRequestProperty("Authorization", "Bearer " + code);
hc.setDoOutput(true);
int rCode = hc.getResponseCode();
c++ thats giving me return 400
Poco::URI uri("https://open.faceit.com/data/v4/players?nickname=FadesfasT&game=CSGO");
std::string path(uri.getPathAndQuery());
HTTPClientSession session(uri.getHost(), uri.getPort());
HTTPRequest request(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1);
request.add("Authorization", "Bearer" + token);
request.setContentType("application/json");
session.sendRequest(request);
HTTPResponse response;
std::istream& in_stream = session.receiveResponse(response);
std::ostringstream out_stream;
Poco::StreamCopier::copyStream(in_stream, out_stream);
std::cout << out_stream.str() << std::endl;
The problem with your C++ snippet is that you are mixing an URL containing a HTTPS address with a request targeting HTTP.
My uneducated guess about why the issue does not appear in Java is that it recognizes the 'https' in the address and automatically uses an appropriate handler for that. Fact is, in C++ or at least in POCO you have to pick the appropriate request yourself.
Basically you have 3 options:
Use a HTTP URL with the HTTP request that you have already written.This does not really seem to be an option, because your URL redirects HTTP to HTTPS so this would not work.
Use a HTTPS URL and change your request to HTTPS. It might be more difficult than option 1, but not that hard and there exists a SO question discussing this. To summarize:
Should I be using HTTPSClientSession instead [...] ?
Yes, if you decide to go with this option
Use a library other than POCO, which seems to be the solution in your case as mentioned in the comments. I for example know of CURL and libhttp, which imo are at least as easy to use as POCO, if not easier. The links lead to pages containing examples on how to execute HTTPS requests.

Sending cookies with react native websockets

So I'm using react native websockets but cannot figure out how i can include cookies in websockets, any suggestions?
At the moment there is no automatic way to do it. There is a third (undocumented) parameter for the WebSocket constructor to pass custom HTTP headers to the connect request.
WebSocket(url, '', {Cookie: 'key=value'});
This works on iOS, I haven't tested it on Android but the WebSocket implementation looks like it is supported there as well.
If you just need to pass a session id or auth token, it's probably easier to pass it as a GET param in the url. Relying on undocumented behavior in a rapidly changing framework can be dangerous.
If you look at the WebSocket declaration, you can see that the header keys should be strings.
This works for me:
var headers = {};
headers["cookie"] = `cookieName=${cookieValue}`;
const ws = new WebSocket(`wss://www.somesite.com/socket`, null, {
headers
});
not this:
{
headers: {
cookie: `cookieName=${cookieValue}`
}
}
As of React Native 0.38, this should happen automatically on Android.
There's currently an open PR for making it work automatically on iOS as well, but at the moment it seems there's still some work left there around testing.
In the meanwhile, you could follow the "manual approach" proposed here:
Manual approach is to retrieve the cookie through a cookie manager plugin and pass it as headers to web socket.
(Once you have the cookie from the manager, the way to pass it to the websocket is, as mentioned previously, to use the undocumented 3rd parameter of WebSocket.)

Setting HTTP headers through Axis2 API

I am using apache axis2 server webservies, Basically I am sending xml response to android client through webservices. Here I need to maintain the session since the services per user basis. I know maintaining session in webservices is bad idea, but cant avoid it.
Actually I need to generate random unique string when user invoke first service from android client, that random string going to be used as session id. This session id, i need to set in http custom header, so that android client can able to get it and can send it subsequent requests as well.
I want to know whether any API is available in axis2 to set custom header information on http headers. Same way I need to read the http header, so that next request I can get the session id from header.
Can anyone advice me regarding this?? Thanks
-Ravi
Dead link on #Martin Dürrmeier's answer, here's a snapshot of the webpage that i've found on web.archive.org : Axis2 - Setting custom HTTP Headers on a response, it helped me.
Here's the lines needed :
MessageContext responseMessageContext =
MessageContext.getCurrentMessageContext().getOperationContext().getMessageContext(
WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
List<Header> headers = new ArrayList<Header>();
headers.add(new Header(HTTPConstants.HEADER_CONTENT_ENCODING, "identity"));
responseMessageContext.setProperty(HTTPConstants.HTTP_HEADERS, headers);