2

I am trying to access a list of users through an app. I cannot get two-legged auth to work. I want to be able to access google's APIs without requiring user consent after install. The gdata lib was deprecated earlier this year, but a business requirement requires accessing the APIs without additional user consent after the domain admin has installed the app.

Here is what I have done so far:

  • I have created an application on the Marketplace. The app manifest declares this scope:

    https://apps-apis.google.com/a/feeds/user/

  • I have installed my app in a test domain and granted permissions for the above scope.

  • I have looked at the samples here: https://code.google.com/p/gdata-python-client/source/browse/samples/oauth/

    • Deprecated Service approach: 2_legged_oauth.py
    • Updated Client approach: TwoLeggedOAuthExample.py

I am using Python 2.7.5 and gdata 2.0.18. Here is my code, which was adapted from the above mentioned examples:

import gdata.gauth
import gdata.apps.client

CONSUMER_KEY = "[snip].apps.googleusercontent.com"
CONSUMER_SECRET = "[snip]"
requestor_id = 'myuser@mydomain.com'

client = gdata.apps.client.AppsClient(domain='mydomain.com', source='myapp-v1')
client.auth_token = gdata.gauth.TwoLeggedOAuthHmacToken(
    CONSUMER_KEY, CONSUMER_SECRET, requestor_id)
client.ssl = True

# Failure occurs here.
feed = client.RetrieveAllUsers()

The response:

<HTML>
<HEAD>
<TITLE>Unknown authorization header</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Unknown authorization header</H1>
<H2>Error 401</H2>
</BODY>
</HTML>

Here are the details for the headers being sent:

GET /a/feeds/mydomain.com/user/2.0?xoauth_requestor_id=myuser%40mydomain.com HTTP/1.1
Host: apps-apis.google.com
Accept-Encoding: identity
GData-Version: 2.0
Authorization: OAuth oauth_nonce="035378574830673", oauth_timestamp="1383593346", oauth_consumer_key="[snip].apps.googleusercontent.com", oauth_signature_method="HMAC-SHA1", oauth_version="1.0", oauth_signature="[snip]"
User-Agent: test-test-v1 gdata-py/2.0.18

Here is debugging information on the response (as taken from putting atom.http_core.ProxiedHttpClient into debug mode):

reply: 'HTTP/1.1 401 Unknown authorization header\r\n'
header: WWW-Authenticate: GoogleLogin realm="http://www.google.com/accounts/ClientLogin", service="apps"
header: Content-Type: text/html; charset=UTF-8
header: Date: Mon, 04 Nov 2013 19:33:35 GMT
header: Expires: Mon, 04 Nov 2013 19:33:35 GMT
header: Cache-Control: private, max-age=0
header: X-Content-Type-Options: nosniff
header: X-Frame-Options: SAMEORIGIN
header: X-XSS-Protection: 1; mode=block
header: Server: GSE
header: Alternate-Protocol: 443:quic
header: Transfer-Encoding: chunked

How do I use use two-legged oauth to access users on a domain? I am open to using the newer Google API clients (oauth2client and apiclient), but only if I can use two-legged authentication since I have a business requirement to not have the third leg.

jon
  • 61
  • 3

1 Answers1

1

I recommend you to read the docs regarding OAuth2 Service Accounts.

2-legged-OAuth is deprecated, gdata APIs are largely deprecated and apiclient services are much cleaner and easier to use.

AMS
  • 244
  • 6
  • 21
  • I was under the impression that I could not use a service account due to the following: 1. http://goo.gl/NDZLj2 - Only certain APIs are supported (>1 year old) 2. your link http://goo.gl/fj9KdX says "act on behalf of an application without accessing user information". I believe I need to access user info. 3. This SO q/a also says that I cannot access user info with a service account: http://goo.gl/utY5us – jon Nov 05 '13 at 15:12
  • If I can use service accounts to access what I want (Admin SDK, Directory API) then I'd much rather use that, I was just under the impression that it was not supported since I will be accessing user data. Is that not accurate? – jon Nov 05 '13 at 15:16
  • My only aversion to using the newer libs and APIs is that I have a business requirement that prevents the third-leg of the OAuth2 flow (additional user consent). – jon Nov 05 '13 at 15:17
  • Please read again the doc (https://developers.google.com/accounts/docs/OAuth2ServiceAccount) and search for Additional Claims ("prn"). It IS possible to impersonate a user with Service Accounts no matter what a 3,742 reputation score user says. We do. You should be able too. – AMS Nov 06 '13 at 09:00
  • The example given in the python api library does not use a 'prn': https://code.google.com/p/google-api-python-client/source/browse/samples/service_account/tasks.py – jon Nov 06 '13 at 14:51
  • Just add a prn=username@thedomain in the SignedJwtAssertionCredentials constructor call and the calls made with this credentials will be made on behalf of that user. – AMS Nov 06 '13 at 18:19
  • Hi Jon, I've been having the exact problem when trying to use oauth2 with gdata. (i am actually migrating code from oauth1 to oauth2, so i have two limitations: using service accounts and using gdata library). How did you solve the problem ? – Meriam-K Oct 23 '14 at 16:28
  • I had a similar problem and solved it with this pattern in my answer: http://stackoverflow.com/questions/26925125/accesstokenrefresherror-google-spreadsheet-api-with-oauth-2-0-service-account-o – Ani Nov 20 '14 at 00:46