Доступ к API реселлера Google с использованием учетных записей служб
У нас возникают проблемы с доступом к API реселлера с использованием учетных записей служб. Пример с клиентскими секретами работает хорошо, но нам нужно было бы развернуть его в k8s (Kubernetes Engine) без необходимости регулярно обновлять сеанс oauth (особенно делать это один раз, так как это довольно сложно в контейнере докера).
Хотя есть много документации о том, как сделать это с помощью Python, мы не смогли найти какой-либо способ получить доступ с помощью служебной учетной записи.
Мы попробовали две учетные записи, по умолчанию один и тот же движок вычислений, созданный непосредственно для нашего варианта использования. Оба получили реселлеров в G Suite.
https://www.googleapis.com/auth/apps.order,
https://www.googleapis.com/auth/admin.directory.user,
https://www.googleapis.com/auth/siteverification,
Мы продолжаем получать "googleapi: Error 403: Authenticated user is not authorized to perform this action., insufficientPermissions"
ошибки, хотя при использовании
client, err = google.DefaultClient(ctx, reseller.AppsOrderScope)
if err != nil {
log.Fatal("creating oauth client failed", zap.Error(err))
}
subs, err := client.Subscriptions.List().Do()
if err != nil {
log.Fatal("listing subscriptions failed", zap.Error(err))
}
Я прочитал в посте Stackru, что API Reseller требует олицетворения пользователя, но поиск по нему в Google и репозиториях oauth2 и клиентских lib не привел к такому способу. Python делает это так, как описано в сквозном руководстве
credentials = ServiceAccountCredentials.from_json_keyfile_name(
JSON_PRIVATE_KEY_FILE,
OAUTH2_SCOPES).create_delegated(RESELLER_ADMIN_USER)
но для Go я не мог найти какой-либо документированный способ сделать это.
2 ответа
Проблема была решена путем использования другого конфига и установки jwt.Subject, который, очевидно, выполняет олицетворение:
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
if filename := os.Getenv(envVar); filename != "" {
serviceAccount, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal("creating oauth client failed", zap.Error(err))
}
config, err := google.JWTConfigFromJSON(serviceAccount,
reseller.AppsOrderScope,
)
config.Subject = *impersonationUser // like user@google.com
client = config.Client(ctx)
}
Вот несколько моментов:
- Reseller API требует только олицетворения / делегирования всего домена при использовании учетной записи службы. Другими словами, сама учетная запись службы не имеет прав на прямой вызов API, но она может выдавать себя за пользователя-посредника (например, admin@reseller.example.com или тому подобное), который имеет права на вызов API-посредника.
- Возможно, вы сможете использовать обычный 3- сторонний OAuth вместо служебной учетной записи. Вам просто нужно убедиться, что вы запрашиваете доступ в автономном режиме, чтобы получить токен обновления, который является долгоживущим.
- Олицетворение / делегирование всего домена несовместимо со стандартными учетными записями служб, встроенными в AppEngine и ComputeEngine. Вы должны использовать служебную учетную запись, созданную в вашем проекте API.
Посмотрите, приведут ли примеры, которые Google предоставляет вам, где вы должны быть.