谷歌应用程序API 403错误与服务帐号

huangapple go评论72阅读模式
英文:

Google Apps API 403 with Service Account

问题

我一直在尝试使用Google的Admin API来查询我的Google Apps组织中的所有用户。我有权限在web UI示例中进行此查询并获取结果,但是当我尝试使用服务帐号进行查询时,会返回403错误。

import (
	"fmt"
	"io/ioutil"
	"log"

	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	directory "google.golang.org/api/admin/directory_v1"
)

func main() {
	serviceAccountJSON, err := ioutil.ReadFile(serviceAccountFile)
	if err != nil {
		log.Fatalf("Could not read service account credentials file, %s => {%s}", serviceAccountFile, err)
	}
	config, err := google.JWTConfigFromJSON(serviceAccountJSON,
		directory.AdminDirectoryUserScope,
		directory.AdminDirectoryUserReadonlyScope,
	)

	client, err := directory.New(config.Client(context.Background()))
	if err != nil {
		log.Fatalf("Could not create directory service client => {%s}", err)
	}

	users, err := client.Users.List().ViewType(publicDataView).Domain(domain).Do()
	if err != nil {
		log.Fatalf("Failed to query all users => {%s}", err)
	}

	for _, u := range users.Users {
		fmt.Println(u.Name.FullName)
	}
}

每次执行时都会返回403错误。相同的查询参数在这里的“Try it!”部分中可以正常工作,所以我不确定为什么会失败。

结果:Failed to query all users => {googleapi: Error 403: Not Authorized to access this resource/api, forbidden}

英文:

I've been trying make a query against Google's Admin API to list all users in my Google Apps Organization. I have permissions to make this query in the web UI example and get results, but it 403's when I try to make the query with a service account.

import (
	"fmt"
	"io/ioutil"
	"log"

	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	directory "google.golang.org/api/admin/directory_v1"
)

func main() {
	serviceAccountJSON, err := ioutil.ReadFile(serviceAccountFile)
	if err != nil {
		log.Fatalf("Could not read service account credentials file, %s => {%s}", serviceAccountFile, err)
	}
	config, err := google.JWTConfigFromJSON(serviceAccountJSON,
		directory.AdminDirectoryUserScope,
		directory.AdminDirectoryUserReadonlyScope,
	)

	client, err := directory.New(config.Client(context.Background()))
	if err != nil {
		log.Fatalf("Could not create directory service client => {%s}", err)
	}

	users, err := client.Users.List().ViewType(publicDataView).Domain(domain).Do()
	if err != nil {
		log.Fatalf("Failed to query all users => {%s}", err)
	}

	for _, u := range users.Users {
		fmt.Println(u.Name.FullName)
	}
}

Every time I execute I get a 403. The same query parameters works in the Try it! section here so I'm not sure why it fails.

result: Failed to query all users => {googleapi: Error 403: Not Authorized to access this resource/api, forbidden}

答案1

得分: 5

我知道这个问题已经有一年了,但我在任何地方都找不到相关信息,但是在遇到与你相同的错误后,我刚刚成功解决了它。

基本上,你需要为你的配置设置一个委托用户,例如:

func main() {
    serviceAccountJSON, err := ioutil.ReadFile(serviceAccountFile)
    if err != nil {
        log.Fatalf("Could not read service account credentials file, %s => {%s}", serviceAccountFile, err)
    }
    config, err := google.JWTConfigFromJSON(serviceAccountJSON,
        directory.AdminDirectoryUserScope,
        directory.AdminDirectoryUserReadonlyScope,
    )

    // 添加我
    config.Subject = "someone@example.com"

    client, err := directory.New(config.Client(context.Background()))
    if err != nil {
        log.Fatalf("Could not create directory service client => {%s}", err)
    }

    users, err := client.Users.List().ViewType(publicDataView).Domain(domain).Do()
    if err != nil {
        log.Fatalf("Failed to query all users => {%s}", err)
    }

    for _, u := range users.Users {
        fmt.Println(u.Name.FullName)
    }
}

参考:https://github.com/golang/oauth2/blob/master/google/example_test.go#L118

希望这对其他人有所帮助!

英文:

I know this question is a year old, but I couldnt find anything about this anywhere - but ive just managed to fix it after running into the same error as you.

basically you need to set a delegation user to your config, eg:

func main() {
    serviceAccountJSON, err := ioutil.ReadFile(serviceAccountFile)
    if err != nil {
        log.Fatalf("Could not read service account credentials file, %s => {%s}", serviceAccountFile, err)
    }
    config, err := google.JWTConfigFromJSON(serviceAccountJSON,
        directory.AdminDirectoryUserScope,
        directory.AdminDirectoryUserReadonlyScope,
    )

    // Add me
    config.Subject = "someone@example.com"

    client, err := directory.New(config.Client(context.Background()))
    if err != nil {
        log.Fatalf("Could not create directory service client => {%s}", err)
    }

    users, err := client.Users.List().ViewType(publicDataView).Domain(domain).Do()
    if err != nil {
        log.Fatalf("Failed to query all users => {%s}", err)
    }

    for _, u := range users.Users {
        fmt.Println(u.Name.FullName)
    }
}

See https://github.com/golang/oauth2/blob/master/google/example_test.go#L118

hope this helps someone else!

答案2

得分: 0

@Chronojam的回复帮我节省了几个小时的时间,但是在较新的Google SDK版本中,directory.New已经被弃用了。你可以通过将directory.New(...)这一行替换为以下代码来实现相同的功能:

client, err := directory.NewService(context.Background(), option.WithHTTPClient(config.Client(context.Background())))
英文:

The @Chronojam reply saved me hours, however on the newer versions of the Google SDK directory.New is deprecated, you should be achieve the same thing replacing the directory.New(...) line with this one instead:

	client, err := directory.NewService(context.Background(), option.WithHTTPClient(config.Client(context.Background())))

huangapple
  • 本文由 发表于 2015年7月17日 07:33:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/31466252.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定