directory_v1始终从云函数返回403 [英] directory_v1 always returns 403 from a cloud function

查看:79
本文介绍了directory_v1始终从云函数返回403的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已遵循: https://developers中提到的步骤.google.com/admin-sdk/directory/v1/guides/delegation

服务帐户具有所有必要的域范围内的委托.

Service account has all the necessary domain wide delegations.

我希望在云函数中运行下面提到的代码,而无需将凭据传递给构建方法,但是它总是返回403-感谢帮助

I wish to run below mentioned code in cloud function without passing credentials to build method, but it always returns 403- help appreciated

import pickle
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

# If modifying these scopes, delete the file token.pickle.
SCOPES = ['https://www.googleapis.com/auth/admin.directory.user']


def directory_api(request):
    """Shows basic usage of the Admin SDK Directory API.
    Prints the emails and names of the first 10 users in the domain.
    """
    creds = None
    # The file token.pickle stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists('token.pickle'):
        with open('token.pickle', 'rb') as token:
            creds = pickle.load(token)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'credentials.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open('token.pickle', 'wb') as token:
            pickle.dump(creds, token)
    print("before build")
    service = build('admin', 'directory_v1')

    # Call the Admin SDK Directory API
    print('Getting the first 10 users in the domain')
    try:
        results = service.users().list(domain="sss.com", viewType="domain_public").execute()
        print(results)
        users = results.get('users', [])
    except Exception as excs:
        print(excs)


    if not users:
        print('No users in the domain.')
    else:
        print('Users:')
        for user in users:
            print(u'{0} ({1})'.format(user['primaryEmail'],
                                      user['name']['fullName']))
    return "ok"

推荐答案

问题:

您正在尝试访问私有资源,但未提供任何凭据.因此,您得到的是 403 .

您还谈到了一个服务帐户,但是共享的代码对应于使用常规帐户进行身份验证(无论如何您都不使用这些凭据,但这不是您使用服务帐户构建凭据的方式).

Also, you talked about a Service Account, but the code you shared corresponds to authenticating with a regular account (you're not using these credentials anyway, but that's not how you build credentials with a Service Account).

如果您不执行以下操作,则没有必要向服务帐户授予域范围的委派(DWD):

It's no use to grant domain-wide delegation (DWD) to a Service Account, if you don't do the following:

  • 使用服务帐户凭据模拟一个普通帐户,该帐户有权访问您尝试访问的资源(在这种情况下,可能是管理员用户). DWD的目的是服务帐户可以代表域中的任何用户执行操作.但是您必须指定要模拟服务帐户的用户,否则服务帐户的行为就好像您根本没有授予DWD一样.
  • 构建服务时,请使用上一步中获取的委派凭据.
  • Use the Service Account credentials to impersonate a regular account who has access to the resource you are trying to access (probably an admin user in this case). The purpose of DWD is that the Service Account can act on behalf of any user in the domain. But you have to specify which user you want the Service Account to impersonate, otherwise the Service Account will behave as if you hadn't granted DWD at all.
  • Use the delegated credentials retrieved in previous step when building the service.

实际上,您所引用的页面上有一个有关如何使用服务帐户委派凭据的示例,请检查

Actually, the page you referenced has an example of how to delegate credentials with a Service Account, check this.

一个更适合您的需求并且使用JSON代替P12的示例可能是这样的:

An example more adapted to your needs, and using JSON instead of P12, could be this:

from google.oauth2 import service_account
from googleapiclient.discovery import build

SCOPES = ['https://www.googleapis.com/auth/admin.directory.user']
SERVICE_ACCOUNT_FILE = 'credentials.json'

def listUsers():
    creds = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    delegatedCreds = creds.with_subject('your-admin-account@sss.com')
    service = build('admin', 'directory_v1', credentials=delegatedCreds)
    # Call the Admin SDK Directory API
    print('Getting the first 10 users in the domain')
    try:
        results = service.users().list(domain="sss.com", viewType="domain_public").execute()
        print(results)
        users = results.get('users', [])
    except Exception as excs:
        print(excs)
    if not users:
        print('No users in the domain.')
    else:
        print('Users:')
        for user in users:
            print(u'{0} ({1})'.format(user['primaryEmail'],
                                      user['name']['fullName']))
    return "ok"

参考:

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆