Доступ к 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 предоставляет вам, где вы должны быть.

Другие вопросы по тегам