Using Google API Java Client on Android, a POST request does not seem to authenticate with Google App Engine app using OAuth

StackOverflow https://stackoverflow.com/questions/8870670

Вопрос

I have an Android client that needs to authenticate with a python Google App Engine app using OAuth. I followed this article.

And was able to successfully do so using an HTTP Get Request. The Android client uses the package com.google.api.client to accomplish this:

OAuthHmacSigner _signer;
HttpTransport TRANSPORT = new NetHttpTransport();
_signer = new OAuthHmacSigner();
_signer.clientSharedSecret = CONSUMER_SECRET;

// STEP1: get a request token
OAuthGetTemporaryToken requestToken = new OAuthGetTemporaryToken(REQUEST_TOKEN_URL);
requestToken.consumerKey = CONSUMER_KEY;
requestToken.transport = TRANSPORT;
requestToken.signer = _signer;
requestToken.callback = "http://my_app_specific_callback";
requestTokenResponse = requestToken.execute();
OAuthAuthorizeTemporaryTokenUrl authorizeUrl = new OAuthAuthorizeTemporaryTokenUrl(AUTHORIZE_URL);
authorizeUrl.temporaryToken = requestTokenResponse.token;
// at this point, redirect the user using a WebView to the URL string returned by authorizeUrl.build().  Continue below once the user has granted request.

// STEP2: get an access token
_signer.tokenSharedSecret = requestTokenResponse.tokenSecret;
OAuthGetAccessToken accessToken = new OAuthGetAccessToken(ACCESS_TOKEN_URL);
accessToken.consumerKey = CONSUMER_KEY;
accessToken.signer = _signer;
accessToken.transport = TRANSPORT;
accessToken.temporaryToken = requestTokenResponse.token;
accessTokenResponse = accessToken.execute();

// STEP3: use the access token acquired above to access a protected resource
_signer.tokenSharedSecret = accessTokenResponse.tokenSecret;
OAuthParameters parameters = new OAuthParameters();
parameters.consumerKey = CONSUMER_KEY;
parameters.token = accessTokenResponse.token;
parameters.signer = _signer;
HttpRequestFactory factory = TRANSPORT.createRequestFactory(parameters);
HttpRequest req = factory.buildGetRequest(new GenericUrl(PROTECTED_URL_GET_USER_EMAIL));
com.google.api.client.http.HttpResponse resp = req.execute();

In the above code snippet, all the 3 steps work just fine. And on my Google App Engine server, I inspected the GET request made to the PROTECTED_URL_GET_USER_EMAIL, and it contained a proper authentication HTTP Header:

'Authorization': 'OAuth oauth_consumer_key="shiprack-test1.appspot.com", oauth_nonce="...", oauth_signature="...", oauth_signature_method="HMAC-SHA1", oauth_timestamp="...", oauth_token="..."'

Using the oauth python package on GAE (google.appengine.api.oauth), my server is able to authenticate the user and determine the user's email address (oauth.get_current_user()).

However, the problem is when I convert the PROTECTED_URL_GET_USER_EMAIL to an HTTP Post request. This is how I do that:

Map<String, String> paramsMap = new HashMap<String, String>();
paramsMap.put("param1", "value1")
paramsMap.put("param2", "value2")
HttpRequest req = _httpRequestFactory.buildPostRequest(new GenericUrl(url), new UrlEncodedContent(paramsMap));
req.setFollowRedirects(true);
com.google.api.client.http.HttpResponse resp = req.execute();

But now, on the GAE python server side, I'm not able to determine the current user. The HTTP Headers contain the same OAuth Authentication headers (with a different nonce, timestamp and signature, but the same oauth token). The "param1" and "param2" are in the HTTP Payload. Perhaps my POST request is not constructed properly?

I used Ikai Lan's (Google App Engine support team) code for a python client to authenticate against my GAE server. And this worked too... the original client with the GET request, and even when I modified it to use a POST request. I noticed though that with the POST request, the oauth parameters were included as URL encoded values in the HTTP payload instead of the in the HTTP header. Is this a requirement for Oauth-signed HTTP post requests?

Thanks in advance!

Это было полезно?

Решение

Unfortunately, proper OAuth 1.0a encoding based on form-encoded HTTP content parameters is not implemented yet. We've gotten quite a few requests for this. There is a feature request already open for it.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top