0

I've got an application with several successful Google API integrations. I'm hitting a roadblock trying to add Gmail integration into the mix. I'm using the .NET API, Google.Apis.Gmail.v1 (version 1.9.0.140).

Here's my code showing a successful Drive API call followed by the Gmail API call that fails:

var drive = new DriveService(Context.GoogleOAuthInitializer);
var list = drive.Files.List().Execute();
Console.WriteLine(list.Items.Count);
// Output: 100 (first page of results)

var gmail = new GmailService(Context.GoogleOAuthInitializer);
var result = gmail.Users.Drafts.List("me").Execute();
// Throws exception described below

The .NET exception provides this information:

Google.Apis.Requests.RequestError
Forbidden [403]
Errors [
    Message[Forbidden] Location[ - ] Reason[forbidden] Domain[global]
]

I'm using the following scopes to get the OAuth token. When I added the gmail scope, I was (as expected) prompted again by Google, "Do you want to give this application access to your email?" I also enabled the gmail API in the Google API Console.

https://www.google.com/m8/feeds
https://www.googleapis.com/auth/drive
https://www.googleapis.com/auth/cloudprint
https://www.googleapis.com/auth/userinfo.email
https://mail.google.com/
    * https://www.googleapis.com/auth/gmail.compose was tried as well

Really wish there was something more helpful in the message to point me in the right direction!!!

Eric D
  • 6,901
  • 1
  • 15
  • 26
pettys
  • 2,293
  • 26
  • 38

2 Answers2

2

I had rolled my own OAuth implementation, and I had this code to add the authorization header:

void IConfigurableHttpClientInitializer.Initialize(ConfigurableHttpClient httpClient) {
    string auth = string.Format("AuthSub token=\"{0}\"", GoogleOAuthToken);
    httpClient.DefaultRequestHeaders.Add("Authorization", auth);
}

and this worked fine for the Drive, CloudPrint, and Contacts API's, but for some reason the Gmail API's needed this:

void IConfigurableHttpClientInitializer.Initialize(ConfigurableHttpClient httpClient) {
    string auth = string.Format("Bearer {0}", GoogleOAuthToken);
    httpClient.DefaultRequestHeaders.Add("Authorization", auth);
}

Makes sense, I guess, although I don't know why the API's would act differently.

Edit: Use of AuthSub for the Google API's has been deprecated: https://developers.google.com/accounts/docs/AuthSub

pettys
  • 2,293
  • 26
  • 38
0

The Gmail API is newer than those and doesn't accept older authentication formats that other Google APIs may--it only accepts oauth2. I wouldn't roll your own authentication, there should be reasonable libraries for doing it in .net.

Eric D
  • 6,901
  • 1
  • 15
  • 26
  • I wouldn't either, today. :) Two years ago when this project first went to production the reasonableness of the available libraries was a little different. And the basic OAuth2 token exchange isn't terribly involved. – pettys Oct 27 '14 at 23:34