You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用Classroom API registrations().create()返回无权限错误求助

Google Classroom API registrations.create() 返回403权限错误排查方案

问题背景

已完成以下配置,但调用Classroom API的registrations().create()接口时仍返回403权限错误:

  • 为Google Workspace配置了域级委托权限
  • 给classroom-notifications@system.gserviceaccount.com授予了Pub/Sub主题的IAM权限
  • 使用超级管理员账号no-reply@nemk.ukr.education作为委托账号

错误信息:

googleapiclient.errors.HttpError: <HttpError 403 when requesting https://classroom.googleapis.com/v1/registrations?alt=json returned "The caller does not have permission". Details: "The caller does not have permission">

用户提供的代码:

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

SCOPES = ['https://www.googleapis.com/auth/classroom.push-notifications', 'https://www.googleapis.com/auth/classroom.rosters']

body = {
        "feed": {
                "feedType": "COURSE_WORK_CHANGES",
                "courseWorkChangesInfo": {
                        "courseId": (courseId)
                },
        },
        "cloudPubsubTopic": {
                "topicName": "projects/(my-project)/topics/coursework-notifications"
        }
}

def main():
        service_account = 'secrets.json'
        credentials = Credentials.from_service_account_file(
        service_account, scopes=SCOPES)
        delegate = credentials.with_subject("no-reply@nemk.ukr.education")

        service = build('classroom', 'v1', credentials=delegate)
        try:
                result = service.registrations().create(body=body).execute()
                print(result)
        except Exception as error:
               print(error.content)
               print(dir(error))
if __name__ == '__main__':
    main()

排查与解决步骤

  • 检查域级委托的API范围配置
    登录Google Admin控制台,进入安全 > API控制 > 域级委托,确认已为目标服务账号添加以下完整OAuth2范围:
    https://www.googleapis.com/auth/classroom.push-notifications、https://www.googleapis.com/auth/classroom.rosters
    注意范围不能有拼写错误,配置保存后需等待15-30分钟生效。

  • 验证Pub/Sub主题的IAM权限
    除了给classroom-notifications@system.gserviceaccount.com添加roles/pubsub.publisher权限,还要确认代码中使用的服务账号(对应secrets.json的账号)拥有roles/pubsub.admin或roles/pubsub.editor权限——创建注册时需要验证主题所有权。同时检查权限列表,确保没有被其他规则覆盖。

  • 确认委托账号的实际权限
    尽管no-reply@nemk.ukr.education是超级管理员,仍需确认:

    1. 该账号未被限制API访问(Admin控制台安全 > API权限中未禁用Classroom API)
    2. 账号能正常访问目标课程的作业资源(直接登录Classroom网页端验证)
  • 修正代码参数问题

    1. 移除courseId值的多余括号,改为"courseId": courseId
    2. 将(my-project)替换为实际的Google Cloud项目ID,确保topicName完全正确
  • 验证服务账号的域级委托状态
    登录Google Cloud控制台,找到目标服务账号,在详情页的“高级设置”中确认域级委托已开启,且该账号已在Google Admin控制台中被标记为可信OAuth客户端。


调整后的示例代码

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

SCOPES = [
    'https://www.googleapis.com/auth/classroom.push-notifications',
    'https://www.googleapis.com/auth/classroom.rosters'
]

# 替换为实际的课程ID和Pub/Sub主题名称
COURSE_ID = "your-actual-course-id"
PUBSUB_TOPIC = "projects/your-project-id/topics/coursework-notifications"

body = {
    "feed": {
        "feedType": "COURSE_WORK_CHANGES",
        "courseWorkChangesInfo": {
            "courseId": COURSE_ID
        }
    },
    "cloudPubsubTopic": {
        "topicName": PUBSUB_TOPIC
    }
}

def main():
    service_account_path = 'secrets.json'
    credentials = Credentials.from_service_account_file(
        service_account_path, scopes=SCOPES
    )
    delegated_credentials = credentials.with_subject("no-reply@nemk.ukr.education")

    service = build('classroom', 'v1', credentials=delegated_credentials)
    try:
        result = service.registrations().create(body=body).execute()
        print("注册成功:", result)
    except Exception as error:
        print("错误详情:", error.content)

if __name__ == '__main__':
    main()

内容的提问来源于stack exchange,提问作者Azazel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 02:25:03