英文:
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())))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论