I am updating an App Engine python project from the old Google Admin SDK API to the new one and having difficulty getting the built in services account (AppAssertionCredentials)authenticated.
I have already
- Enabled the Admin SDK API in the Developers console
- Enabled API access in the Google Apps dashboard
To work around this I created a service account from the Developers console, downloaded the credentials.json, and set the following permissions (without quotes) in the Google Apps dashboard (Security > Advanced settings > Manage API client access) for that account:
- client: "{ service account id }.apps.googleusercontent.com"
- permissions: "https://www.googleapis.com/auth/admin.directory.user.readonly https://www.googleapis.com/auth/admin.directory.group.readonly https://www.googleapis.com/auth/admin.directory.group.member.readonly"
My current code is (redacted slightly)
# ...
import json
from google.appengine.api import memcache
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client.client import SignedJwtAssertionCredentials
GAPPS_CREDENTIALS = 'credentials.json'
GAPPS_SCOPES = [
'https://www.googleapis.com/auth/admin.directory.user.readonly',
'https://www.googleapis.com/auth/admin.directory.group.readonly',
'https://www.googleapis.com/auth/admin.directory.group.member.readonly'
]
GAPPS_ADMIN = 'admin'
GAPPS_DOMAIN = 'domain.com'
GAPPS_USER = 'user'
# ...
with open(GAPPS_CREDENTIALS) as jsonfile:
jsondata = json.load(jsonfile)
credentials = SignedJwtAssertionCredentials(
jsondata['client_email'],
jsondata['private_key'],
scope=GAPPS_SCOPES,
sub=GAPPS_ADMIN+'@'+GAPPS_DOMAIN
)
http = credentials.authorize(Http(memcache))
apps = build('admin', 'directory_v1', http=http)
user = apps.users().get(userKey=GAPPS_USER +'@'+GAPPS_DOMAIN ).execute()
console.log(user['email'])
# ...
This works perfectly, however if I can, I would like to eliminate the credentials.json file by using a AppAssertionCredentials
call to authenticate.
As soon as I run the following code, however:
# ...
import json
from google.appengine.api import memcache
from googleapiclient.discovery import build
from httplib2 import Http
from oauth2client.appengine import AppAssertionCredentials
GAPPS_CREDENTIALS = 'credentials.json'
GAPPS_SCOPES = [
'https://www.googleapis.com/auth/admin.directory.user.readonly',
'https://www.googleapis.com/auth/admin.directory.group.readonly',
'https://www.googleapis.com/auth/admin.directory.group.member.readonly'
]
GAPPS_ADMIN = 'admin'
GAPPS_DOMAIN = 'domain.com'
GAPPS_USER = 'user'
# ...
credentials = AppAssertionCredentials(scope=GAPPS_SCOPES,sub=GAPPS_ADMIN+'@'+GAPPS_DOMAIN)
http = credentials.authorize(Http(memcache))
apps = build('admin', 'directory_v1', http=http)
user = apps.users().get(userKey=GAPPS_USER +'@'+GAPPS_DOMAIN ).execute()
console.log(user['email'])
# ...
I get a 403 error:
<HttpError 403 when requesting https://www.googleapis.com/admin/directory/v1/users/user%domain.com?alt=json returned "Not Authorized to access this resource/api">
I suspect the issue may be that the built-in service account is not authenticated in Google Apps Dashboard, however I am unable to find the account domain either in the Developers Console or the App Engine Console to be able to add these permissions. I have tried:
- adding all the service accounts found under Developers Console > Permissions, changing @developer.gserviceaccount.com to .apps.googleusercontent.com (the @cloudservices.gserviceaccount.com account causes error:
This client name has not been registered with Google yet.
) - using the {project}.appspot.com domain: Google Apps errors with
This client name has not been registered with Google yet.
Can anyone shed any light?
Thanks