directory_v1始终从云函数返回403 [英] directory_v1 always returns 403 from a cloud function
问题描述
我已遵循: 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"
参考:
- 为服务器到服务器应用程序使用OAuth 2.0
- 执行G Suite域范围的授权 a>
- Using OAuth 2.0 for Server to Server Applications
- Perform G Suite Domain-Wide Delegation of Authority
Reference:
这篇关于directory_v1始终从云函数返回403的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!