trungtoanit / gdata-objectivec-client

Automatically exported from code.google.com/p/gdata-objectivec-client
0 stars 0 forks source link

Unknown authorization header error when using OAuth authorization #81

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Use the OAuth touch view controllers to have the user authorize the 
application
2. Use the OAuth as an authorizer on a google service such as the calendar 
service.
3. Make a request (such as fetchFeedWithUrl).

What is the expected output? What do you see instead?

I should see the calendar feed for the authorized user.  Instead, I see a 401 
error: Unknown authorization header.

What version of the product are you using? On what operating system?

This is on iPhone.

Please provide any additional information below.

Original issue reported on code.google.com by visig...@gmail.com on 1 Dec 2010 at 7:50

GoogleCodeExporter commented 9 years ago
Try specifying a scope string using the http scheme, like

scope = @"http://www.google.com/calendar/feeds/";
windowController = [[[GDataOAuthWindowController alloc] initWithScope:scope ...

Original comment by gregrobbins on 1 Dec 2010 at 7:14

GoogleCodeExporter commented 9 years ago
i use [GDataServiceGoogleCalendar authorizationScope] in this regard:

GDataOAuthViewControllerTouch *signInViewController = 
    [[[GDataOAuthViewControllerTouch alloc]
      initWithScope:[GDataServiceGoogleCalendar authorizationScope]
      language:nil appServiceName:kAppServiceName delegate:self
      finishedSelector:@selector(viewController:finishedWithAuth:error:)] 
     autorelease];

then, later, when my app starts up again, i use:

[GDataOAuthViewControllerTouch authForGoogleFromKeychainForName:kAppServiceName]

Original comment by visig...@gmail.com on 2 Dec 2010 at 8:06

GoogleCodeExporter commented 9 years ago
i should add that, on the first time through, the second line above does not 
get run - i just use the result of the OAuth sign in view controller returned 
in viewController:finishedWithAuth:error:

either way, i get the same error.

Original comment by visig...@gmail.com on 2 Dec 2010 at 8:14

GoogleCodeExporter commented 9 years ago
Try with the scope @"http://www.google.com/calendar/feeds/" instead of calling 
GDataServiceGoogleCalendar authorizationScope]

Original comment by grobb...@google.com on 2 Dec 2010 at 11:43

GoogleCodeExporter commented 9 years ago
I'm guessing your point was to use an http:// endpoint instead of an https:// 
endpoint.  Unfortunately, I still get the same error.

I made sure to reset state in my iPhone simulator, so I had to go through the 
Google OAuth flow once again.

I tried using the Charles debugging proxy to get a trace of the traffic, but 
the library connects via SSL so this didn't work.  I dumped the URL request and 
here is what I got.  Note that the OAuth header is all one HTTP header field.

2010-12-02 23:58:22.454 Hindsight[24682:207] GET 
https://www.googleapis.com/userinfo/email
2010-12-02 23:58:22.455 Hindsight[24682:207] Authorization: OAuth 
oauth_consumer_key="anonymous", 
oauth_token="1%2F__K1QEV4rN-4uuQSjtnOvLPKB7_p3r5U8hywAKk34LQ", 
oauth_signature_method="HMAC-SHA1", oauth_version="1.0", 
oauth_nonce="12538816366109425351", oauth_timestamp="1291363102", 
oauth_signature="OQdThBfMbxJPBU4clB1BX2XBprE%3D"

Original comment by visig...@gmail.com on 3 Dec 2010 at 8:01

GoogleCodeExporter commented 9 years ago
Oops, that was the initial user sign info request which seems to succeed.  Here 
is a request from my app that seems to fail:

2010-12-03 00:02:30.213 Hindsight[24682:207] GET 
https://www.google.com/calendar/feeds/default/owncalendars/full
2010-12-03 00:02:30.214 Hindsight[24682:207] Gdata-Version: 2.1
2010-12-03 00:02:30.214 Hindsight[24682:207] Authorization: OAuth 
oauth_consumer_key="anonymous", 
oauth_token="1%2F__K1QEV4rN-4uuQSjtnOvLPKB7_p3r5U8hywAKk34LQ", 
oauth_signature_method="HMAC-SHA1", oauth_version="1.0", 
oauth_nonce="10755213611383845164", oauth_timestamp="1291363350", 
oauth_signature="oktvwxCh2GAKT2d1iIzreZ4sn7M%3D"
2010-12-03 00:02:30.214 Hindsight[24682:207] User-Agent: 
com.yourcompany.Hindsight-1.0 GData-ObjectiveC/1.11 iPhone_Simulator/4.1 (gzip)

Original comment by visig...@gmail.com on 3 Dec 2010 at 8:03

GoogleCodeExporter commented 9 years ago
To test this, in the OAuthSample application, I changed the scope string in the 
signInToGoogle method to @"https://www.google.com/calendar/feeds/" and the 
urlStr string in the doAnAuthenticatedAPIFetch method to 
@"https://www.google.com/calendar/feeds/default/owncalendars/full", and 
fetching returned a 401 Unknown authorization header response.

Then I changed the scope string to the non-SSL 
@"http://www.google.com/calendar/feeds/" and the API fetch succeeded.

Incidentally, the GData/GTMHTTPFetcher class has built-in logging; just add the 
logging .h/.m files to your project, and call the class setIsLoggingEnabled: 
method.

Original comment by gregrobbins on 4 Dec 2010 at 3:05

GoogleCodeExporter commented 9 years ago
sorry it has taken me so long to try this out.  oddly enough, i tried the same 
thing you did: i used the OAuthSample application and changed the same strings. 
 I still got Unknown Authorization Header!

so, i created a brand new google account and found out that this bug has to do 
with my account.  my new account worked, but i got the message: "you must be a 
calendar user to use private feeds."  i think, at least, this means the OAuth 
header was read & verified, but a deeper API call failed.

could you by any chance intro me to someone with whom i could debug this issue 
with my account?

Original comment by visig...@gmail.com on 26 Dec 2010 at 11:13

GoogleCodeExporter commented 9 years ago
What kind of account is exhibiting the problem? Is it a google apps account? 
Does it have second-factor authorization turned on?

Original comment by grobb...@google.com on 28 Dec 2010 at 8:37

GoogleCodeExporter commented 9 years ago
it's a basic google account i started a very long time ago - when gmail first 
started.  i've since activated a number of services with the same account 
(calendar, iGoogle, AdWords, etc.).

it does not have two-factor auth turned on.  i only authenticate with a 
password for the time being.

Original comment by visig...@gmail.com on 28 Dec 2010 at 8:59

GoogleCodeExporter commented 9 years ago
I think I've tracked this one down a bit - there is a difference in the 302 
redirect processing between [NSURLConnection sendSynchronousRequest] and 
[service fetchFeedWithURL].

The OAuthSampleTouch application works fine - but it is just using the direct 
sendSynchronousRequest method. If you use fetchFeedWithURL it fails. 

I can't get good tracing for sendSynchronousRequest to see how it is handling 
the 302 redirect (to add gsessionid per Calendar API), but for fetchFeedWithURL 
I get the following request/responses:

request: GET URL: 
https://www.google.com/accounts/OAuthGetRequestToken?xoauth_displayname=BrewCal&
scope=https%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%20https%3A%2F%2Fwww.google
apis.com%2Fauth%2Fuserinfo%23email

response: 200 

request: GET URL: https://www.google.com/accounts/OAuthGetAccessToken
response: 200

request: GET URL: https://www.googleapis.com/userinfo/email
response: 200

request: GET URL: https://www.google.com/calendar/feeds/nichenke%40gmail.com
response: 302

request: GET URL: 
https://www.google.com/calendar/feeds/nichenke%40gmail.com?gsessionid=sWVqZzKEkw
y7BlqWhJpwIg

If we look at the headers for the last two requests, we can see the OAuth data 
- specifically that the headers are being copied over blindly by 
GDataHTTPFetcher instead of getting resigned with the new URL.

Authorization: OAuth oauth_consumer_key="anonymous", oauth_token="_snip_", 
oauth_signature_method="HMAC-SHA1", oauth_version="1.0", 
oauth_nonce="9119831626062417141", oauth_timestamp="1300378439", 
oauth_signature="IG29IsKcWfly%2FFl5yoEE4%2FV7ZSo%3D"

then in the 302 request:
  Authorization: OAuth oauth_consumer_key="anonymous", oauth_token="_snip_", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_nonce="9119831626062417141", oauth_timestamp="1300378439", oauth_signature="IG29IsKcWfly%2FFl5yoEE4%2FV7ZSo%3D"

If I walk through this in http://googlecodesamples.com/oauth_playground, I can 
get the XML just fine after a redirect, but the oauth_signature changes between 
the original request and the 302 redirect GET.

Original comment by niche...@gmail.com on 17 Mar 2011 at 4:36

GoogleCodeExporter commented 9 years ago
This is a gross hack, but if I change GDataHTTPFetcher - (NSURLRequest 
*)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest 
*)redirectRequest redirectResponse:(NSURLResponse *)redirectResponse to not 
change the URL for the redirect, but do everything else it works.

Basically, it just resends the original GET request with the extra "Cookie: 
S=calendar=4YdO23MhB0JKeKo-kM-nzw" to satisfy the gsessionid requirement for 
Calendar.

As an aside - it seems like the Calendar service needs to somehow get this 
session ID back and add it to future requests to prevent the redirect bounces. 

Original comment by niche...@gmail.com on 17 Mar 2011 at 5:14

GoogleCodeExporter commented 9 years ago
There have been updates to the cookie handling in the library during redirects 
- http://code.google.com/p/gdata-objectivec-client/source/detail?r=625

But the library has replaced OAuth 1 with OAuth 2, and the newer protocol does 
not sign requests and so avoids most of compatibility problems of OAuth 1.

Original comment by gregrobbins on 6 May 2011 at 6:09