Log inputs and outputs for debugging OAuth2 authentication

Dec 8, 2014 at 1:03 AM
Hi,

Is there a way to log all the communications that go through the library? I'd like to do that to debug an OAuth2 authentication.

More specifically, I am having trouble modifying the OAuth2Client sample code to make it work with the Google Spreadsheets API. I've added this class to the sample code :
class sheets_session_sample : public oauth2_session_sample {
public:
  sheets_session_sample()
  : oauth2_session_sample(U("Spreadsheets"), s_sheets_key, s_sheets_secret,
                          U("https://accounts.google.com/o/oauth2/auth"),
                          U("https://accounts.google.com/o/oauth2/token"),
                          U("http://localhost:8891")) {
    m_oauth2_config.set_scope(U("https://spreadsheets.google.com/feeds"));
    m_oauth2_config.set_state(U("test"));
    m_oauth2_config.set_bearer_auth(false);
    m_oauth2_config.set_http_basic_auth(false);
  }

protected:
  void run_internal() override {
    http_client api(U("https://spreadsheets.google.com/feeds"), m_http_config);
    ucout << "List : " << api.request(methods::GET,
                                      U("spreadsheets/private/full"))
                              .get()
                              .to_string() << std::endl;
  }
};
And I get an HTTP 401 error on the request : Token invalid - AuthSub token has wrong scope

Thanks,

Romain
Dec 9, 2014 at 5:56 AM
Hi Romain,

Unfortunately we don't have a large, catch-all logging flag. You could add breakpoints to the Win32 system calls which actually send and receive the messages over the network, however.

The best way to diagnose these kinds of issues is to use either wireshark or fiddler. They're both excellent (and free!) tools which will let you inspect network traffic to and from your computer. However, since the target uses SSL, you will need to setup a little test server on your local machine that doesn't use SSL to see the actual messages (target your OAuth client at this server).

roschuma
Dec 17, 2014 at 3:21 AM
Hello Roshuma,

Thanks for your reply. I have built a local test server to see the messages and I've tracked the authentication issue down to the very last step, but I am unable to debug it further.

It seems like retrieving the OAuth token works with the code above, but making the actual API request fails with the error 401 shown above. What surprises me is that once I have the token, I can use it to make a request using curl like so :
curl https://spreadsheets.google.com/feeds/spreadsheets/private/full?access_token=<the access token>
I've built a little Casablanca test program to try to reproduce the curl command :
int main()
{  
  http_client client(U("https://spreadsheets.google.com/"));
  uri_builder builder(U("/feeds/spreadsheets/private/full"));
  builder.append_query(U("access_token"),
                       U("<the request token>"));
  ucout << "Client base URI : " << client.base_uri().to_string() << "\n";
  http_response response =
    client.request(methods::HEAD, builder.to_string()).get();
  ucout << "Response " << response.to_string() << std::endl;
  return 0;
}
I get the 401 'Token invalid' response with this. What should I change in my test program to make it mimic the curl request ?

Thanks,

Romain
Dec 17, 2014 at 5:19 PM
It likely isn't your issue, but why are you using HEAD here? As I understand it, your curl invocation should have sent a GET request.

The only thing I can think of that might cause issues is perhaps some URI encoding issue.

What do the actual requests look like when they're made against your local server (by curl and by the example program you gave)? Are they identical apart from the User-Agent?

roschuma
Dec 18, 2014 at 8:49 PM
It's a typo, I tried both GET and HEAD methods because the curl program works with and without the -I flag.

My test server has this method for handling the API request :
  void handle_resource_request(http_request message) {
    ucout << "Received request : " << message.to_string()
          << std::endl;
  }
Here is the curl command :
curl http://localhost:8888/feeds/spreadsheets/private/full?access_token=MyAccessToken
and the server's output :
Received request : GET http://localhost:8888/feeds/spreadsheets/private/full?access_token=MyAccessToken HTTP/1.1
Accept: */*
Host: localhost:8888
User-Agent: curl/7.37.0
My test program
int main()
{
  http_client client(U("http://localhost:8888/"));
  uri_builder builder(U("feeds/spreadsheets/private/full"));
  builder.append_query(U("access_token"),
                       U("MyAccessToken"));
  http_response response =
    client.request(methods::GET, builder.to_string()).get();
  ucout << "Response " << response.to_string() << std::endl;

  ucout << "Done." << std::endl;

  return 0;
}
and the server's output :
Received request : GET http://localhost:8888/feeds/spreadsheets/private/full?access_token=MyAccessToken HTTP/1.1
Connection: Keep-Alive
Host: localhost:8888
User-Agent: cpprestsdk/2.3.0
Dec 18, 2014 at 9:31 PM
The only thing I can think of would be some encoding issue with the token. You've tried the test program with your actual token instead of "MyAccessToken", right?

Finally, you could look at setting up some more complex proxy like http://www.telerik.com/fiddler to look at the exact communications you're having with the google servers.

roschuma
Dec 19, 2014 at 10:32 AM
Edited Dec 19, 2014 at 11:24 AM
Here is an example of what the modified OAuth2Client sample outputs to the console :
Running Spreadsheets session...
Opening browser in URI:
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=39385340090-r2jec7r307ibe0ldmsc0b48rudp6hkuc.apps.googleusercontent.com&redirect_uri=http://localhost:8891&state=hG02zTTvm3OSaFBeVUg2NJMxdFXrV3kz&scope=https://spreadsheets.google.com/feeds/%20http://spreadsheets.google.com/feeds/

(process:5554): GLib-CRITICAL **: g_slice_set_config: assertion 'sys_page_size == 0' failed
Access token : ya29.4QDxpNy1u7kF1gIeF1vEg61MscpxIc2U7d_3Q2TzfyWP20lftRmMe0Yo8cFpHoliR0JtPMBFcq9NpQ
List : HTTP/1.1 401 Token invalid - AuthSub token has wrong scope
Alternate-Protocol: 443:quic,p=0.02
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Date: Fri, 19 Dec 2014 10:08:37 GMT
Expires: Fri, 19 Dec 2014 10:08:37 GMT
P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
Server: GSE
Set-Cookie: NID=67=uhDcuKK4Xq4lvUhCvYahEWByAVZiTGliiDW73vvZq9U3JmeqVpH_fzFWPfXFk0spr5JTREkra3GhnAAkPp3mszi0Uctp9nZqA_8JNMF42wwLT-OPBYMawmWIzINRk-Mi;Domain=.google.com;Path=/;Expires=Sat, 20-Jun-2015 10:08:37 GMT;HttpOnly
Transfer-Encoding: chunked
WWW-Authenticate: AuthSub realm="https://www.google.com/accounts//AuthSubRequest"
x-chromium-appcache-fallback-override: disallow-fallback
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
When I copy-paste the authorization token in a curl command, the request works :
curl https://spreadsheets.google.com/feeds/spreadsheets/private/full?access_token=ya29.4QDxpNy1u7kF1gIeF1vEg61MscpxIc2U7d_3Q2TzfyWP20lftRmMe0Yo8cFpHoliR0JtPMBFcq9NpQ
Is it possible that the token gets encoded wrong? It looks like there are no special characters in it.

I'll run fiddler to see what the communications are.

Thanks,

Romain
Jan 3, 2015 at 10:39 PM
Hi again, and Happy New Year!

Here are two captures done using Wireshark of the traffic on my computer while running the test program and the curl command :
This capture is done on my Linux development box. It is running Fedora 21 with kernel 3.17.4. I realize that Fedora is not officially supported, but this issue also happens on Ubuntu 14.10 with the latest release of Casablanca (commit 42d9cc069b63). Would it be helpful to put the Wireshark records taken on Ubuntu?

Thanks,

Romain
Jan 25, 2015 at 6:01 PM
I am trying to do something similar but with WordPress plug in called WooCommerce Software As Ad-on over https

This is all the info they provide on how to use their REST API to use OAuth2.
curl https://www.example.com/wc-api/v2/orders \
-u consumer_key:consumer_secret

From a C++ Windows desktop application, VS 2013.
It seems that the first step is working with OAuth2Client and finding documentation on the classes it uses.
When can I find OAuth2Client?

Thanks
Shoshana
Jan 26, 2015 at 7:36 PM
Hi Shoshana,

For documentation on our oAuth features take a look here, see our reference docs, and there is a sample under Release\samples\Oauth2Client.

Steve
Jan 27, 2015 at 1:09 PM
Thanks a bunch