1
votes

I have a Json service file, and a service account that already accesses translate and sheets, but it will not access user lists. The result is either 400 showing its confused or 401 saying its not authorized. Examples are usually about client involved OAuth processes, where I need server to server. I have enabled that "Enable G Suite domain-wide delegation" feature on the service account too.

I read and tried the JWT method, but I get the same error responses. https://developers.google.com/identity/protocols/oauth2/service-account#python_2

My goal is to call either one of these end points https://www.googleapis.com/admin/directory/v1/users https://www.googleapis.com/admin/directory/v1/users.readonly

Any direction would be greatly appreciated.

UPDATE1: This is using the Jwt token approach which yields error 401.

with open(CLIENT_SECRET_FILE, "r+") as fh:
    config = json.load(fh)

iat = time.time()
exp = iat + 3600
payload = {'iss': config['client_email'],
           'sub': config['client_email'],
           'aud': 'https://www.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': config['private_key_id']}
signed_jwt = jwt.encode(payload, config['private_key'], headers=additional_headers,
                        algorithm='RS256')

url = 'https://www.googleapis.com/admin/directory/v1/users'        
headers = {"Authorization": "Bearer " + signed_jwt}
r = requests.get(url, headers=headers)

I have also tried

scopes = ['https://www.googleapis.com/auth/admin.directory.user']
credentials = ServiceAccountCredentials.from_json_keyfile_name(CLIENT_SECRET_FILE, scopes=scopes)
service = build('admin', 'directory_v1', credentials=credentials)
results = service.users().list().execute()

UPDATE2: This link has great information and simple code to review. As much as I tried to avoid impersonation, the AdminSDK requires it. That makes integrations a bit awkward in my view. In addition, the issue I also faced was the Domain-Wide-Delegation screen in the Google Workspace Admin can get messed up. Deleting the entry and recreating it fixed the forever 403 error I kept getting no matter what I had tried. https://gist.github.com/lewisrodgers/fa766ebd37c1397d3a014eb73805edd1

2
You need to show your code and how the service account is configured. The setup and use is fairly complicated (simple once you understand the steps). Most likely you have left out the impersonation step when creating the access token. I have posted other answers on this type of question, search my profile.John Hanley
So there is no way to grant a service account rights to act as a service? If the admin leaves, then all the services stop working until someone reconfigures the background jobs? This seems odd to me. I can manage sheets and gdrive as a service without impersonation.darren
What do you mean by "act as a service" and how is that related to your question? Your comment "if the admin leaves" - the "company" should own/control all accounts that admins use. If they are using personal accounts, setup your identity and access management under company control.John Hanley
I am trying to setup a user sync between Google and another product. It should be independent of a user because it is a system calling a system. My focus on service account was for that purpose. All I really need is readonly access to the users for their name, email, and profile ID.darren
Reread my first comment and update your question.John Hanley

2 Answers

1
votes

You need to incorporate into your code impersonation, so that the service account acts on behalf of the admin

Because only admins have authroization to access Resource: users.

For impersonation in Python you need to implement the additional line

delegated_credentials = credentials.with_subject('[email protected]')
0
votes

The link below has great information and simple code to review. As much as I tried to avoid impersonation, the AdminSDK requires it. That makes integrations a bit awkward in my view.

In addition, the issue I also faced was the Domain-Wide-Delegation screen in the Google Workspace Admin that messed up. After much digging over weeks, I found a simple solution of deleting and recreating the client entry in that screen. It fixed the never ending 403 error that hit every test I tried that should have worked and did for many others.

This seems to be the only API set by Google that requires impersonation, and is annoying when attempting to create a SaaS solution.

Really basic, trimmed examples, and decent article references. https://gist.github.com/lewisrodgers/fa766ebd37c1397d3a014eb73805edd1