Archived Forum Post

Index of archived forum posts

Question:

Login to GMail using OAuth2 authentication

Aug 28 '15 at 14:07

Hi

I try to login to GMail using OAuth2 authentication. I use the sample

Also I created a service account here: Then I downloaded .p12 and replaced iss and sub in example with my values. Unfortunately SvcOauthAccessToken returns null. The tail of the LastErrorText:

       HTTPS secure channel established.
     --openHttpConnection
     connectTime: Elapsed time: 2668 millisec
     startLine: POST /o/oauth2/token HTTP/1.1
     requestHeader(16ms):
       requestHeader: Content-Type: application/x-www-form-urlencoded
                      Host: accounts.google.com
                      Content-Length: 791
     --requestHeader
     computeRequestDataSize:
       Request data contains encoded items..
     --computeRequestDataSize
     sendRequestHeader(16ms):
       sendHeaderElapsedMs: 16
     --sendRequestHeader
     sendRequestBody:
       idleTimeoutMs: 20000
       encodedBody: grant_type=...
       sendBodyElapsedMs: 0
     --sendRequestBody
     readResponseHeader(1092ms):
       responseHeader: HTTP/1.1 401 Unauthorized
                       Content-Type: application/json 
                       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."
                       Date: Thu, 27 Aug 2015 16:27:51 GMT
                       Expires: Thu, 27 Aug 2015 16:27:51 GMT
                       Cache-Control: private, max-age=0
                       X-Content-Type-Options: nosniff
                       X-Frame-Options: SAMEORIGIN
                       X-XSS-Protection: 1; mode=block
                       Server: GSE
                       Set-Cookie: NID=70=...;Domain=.google.com;Path=/;Expires=Fri, 26-Feb-2016 16:27:51 GMT;HttpOnly
                       Alternate-Protocol: 443:quic,p=1
                       Alt-Svc: quic=":443"; p="1"; ma=604800
                       Accept-Ranges: none
                       Vary: Accept-Encoding
                       Transfer-Encoding: chunked
     --readResponseHeader
     statusCode: 401
     statusText: Unauthorized
     readResponseBody(15ms):
       Response is chunked.
     --readResponseBody
   --fullHttpRequest
   computeAuthorization(15ms):
     Password is empty.
   --computeAuthorization
   computeAuthorization failed (2).
   success: 0
 --a_synchronousRequest
 responseStatusCode: 401
 success: 1
--fullRequest
   charset: windows-1252
   responseBody: {
      "error" : "unauthorized_client",
       "error_description" : "Unauthorized client or scope in request."
   }
   access_token not found.
   Failed.

--G_SvcOauthAccessToken2 --ChilkatLog

Can you help me please?


Answer

Make sure to test with v9.5.0.52, which was released yesterday/today. A problem was fixed regarding this..


Answer

Tried v9.5.0.52. Unfortunately the result is the same.


Answer

pass an empty string for "sub". Change this line:

string sub = "user@your-domain.com";
to this:
string sub = "";


Answer

Thank you. I can get a token. But now the method Login fails:

ChilkatLog:
  Login(60903ms):
    DllDate: Aug 26 2015
    ChilkatVersion: 9.5.0.52
    UnlockPrefix: ...
    Username: ...
    Architecture: Little Endian; 64-bit
    Language: .NET 4.0 / x64
    VerboseLogging: 1
    login: user@gmail.com
    authenticateXOAuth2(60887ms):
      xoauth2Imap(60887ms):
        ConnectionType: SSL/TLS
        ImapCmdSent: aaab AUTHENTICATE XOAUTH2
        getCompleteResponse(60872ms):
           ImapCmdResp: + eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2NvcGUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ==
           idleTimeoutMs: 60000
           tlsReadIncoming: Socket operation timeout.
           Failed to receive more TLS applicaton data.
           recvUntilMatch: Socket operation timeout.
           nReceived: 0
           getImapResponseLine: Socket operation timeout.
           Failed to get next response line from IMAP server.
         --getCompleteResponse
      --xoauth2Imap
   --authenticateXOAuth2
   Failed.
 --Login

--ChilkatLog


Answer

I'll give it a test today..


Answer

The timeout is due to the fact that Chilkat wasn't sending an empty response after it received the failed line:

ImapCmdResp: + eyJzdGF0dXMiOiI0MDAiLCJzY2hlb...

This was an easy enough fix. However, I'm a bit confused about all of this because Google never explicitly nor straightforwardly explains what can be done with a "service account". I would've thought that the .p12 one downloads serves as the credentials to get an access token, and then the access token is used to authenticate with GMail.

It seems though for GMail, to use a service account w/ OAuth2, one needs a Google Apps account. The email address associated with the Google Apps account (typically, (or always?) a non "gmail.com" email address is what is accessed. Therefore, the "sub" the non-GMail Google Apps email address. See https://developers.google.com/identity/protocols/OAuth2ServiceAccount

Delegating domain-wide authority to the service account

If your application accesses user data, the service account that you created needs to be granted access to the Google Apps domain’s user data that you want to access.

The following steps must be performed by an administrator of the Google Apps domain:

Go to your Google Apps domain’s Admin console.
Select Security from the list of controls. If you don't see Security

listed, select More controls from the gray bar at the bottom of the page, then select Security from the list of controls. If you can't see the controls, make sure you're signed in as an administrator for the domain. Select Show more and then Advanced settings from the list of options. Select Manage API client access in the Authentication section. In the Client Name field enter the service account's Client ID. In the One or More API Scopes field enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar. Click Authorize.

Your application now has the authority to make API calls as users in your domain (to "impersonate" users). When you prepare to make authorized API calls, you specify the user to impersonate.

I think one can do XOAUTH2 authentication in different ways (without a service account), but these require a callback URL with the assumption there's a human at a browser that's going to approve the request..

When you have an application that manipulates a particular GMail account via the .p12, it requires a Google Apps account (that's what I'm concluding -- but maybe I'm wrong???) Google just never explicitly states it.. it's one of those things they assume is common knowledge but might not be..


Answer

I think one can do XOAUTH2 authentication in different ways (without a service account), but these >require a callback URL with the assumption there's a human at a browser that's going to approve the >request..

Yes it seems this approach works. Thank you.