简体   繁体   中英

Getting AppEngine AppAssertionCredentials working (Python)?

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:

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

To answer the question about where to find the email address form of the App Engine default service account: This is located in the new console under Permissions -> Service Accounts (as opposed to API Manager -> Credentials for service accounts you create yourself).

Now to answer the main question: AppAssertionCredentials won't work for Service Accounts with delegated access, as it does not accept a 'sub' parameter for the constructor and doesn't have a method for creating delegated credentials (it's not used as a keyword argument as with SignedJwtAssertionCredentials, which is now ServiceAccountCredentials , and is ignored). You should still be able to use the App Engine default service account with delegation though, since the new console now allows you to create JSON keys for the default service accounts .

It's potentially possible to support delegated access with AppAssertionCredentials, and for this you could post a feature request on the project issue tracker .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM