Как устранить ошибку при создании общего диска учетной записи службы Google с недостаточными правами доступа?

Я пытаюсь создать общий диск Google, используя свою учетную запись службы, но получаю сообщение об ошибке недостаточного доступа к файлу. Кто-нибудь знает, как создать общий диск Google с помощью учетной записи службы, или может определить, что я здесь делаю не так?

Для простоты использования я создал проект на github, который содержит файлы, представленные здесь. https://gitlab.com/eghm-lab/stackoverflow-google-service-account-test-drive-creation

Я предоставил ошибку, код Java для SOTeamDriveCreate и pom.xml ниже. После размещения SOTeamDriveCreate.java в src / main / java. Следует скопировать файл client_secrets.json учетных данных учетной записи службы в тот же каталог, что и файл pom. Затем выполните:

mvn clean compile ; mvn exec:java -Dexec.mainClass=SOTeamDriveCreate

Ошибка weakFilePermissions:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run(ExecJavaMojo.java:297)
    at java.lang.Thread.run(Thread.java:745)
Caused by: com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
    "code" : 403,
    "errors" : [ {
        "domain" : "global",
        "message" : "The user does not have sufficient permissions for this file.",
        "reason" : "insufficientFilePermissions"
    } ],
    "message" : "The user does not have sufficient permissions for this file."
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
    at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
    at SOTeamDriveCreate.createTeamDrive(SOTeamDriveCreate.java:110)
    at SOTeamDriveCreate.main(SOTeamDriveCreate.java:103)
    ... 6 more

SOTeamDriveCreate.java:

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.TeamDrive;


public class SOTeamDriveCreate {

    /** Application name. */
    private static final String APPLICATION_NAME =
            "Drive API Java Quickstart";


    /** Directory to store user credentials for this application. */
    private static final java.io.File DATA_STORE_DIR = new java.io.File(
            System.getProperty("user.home"), ".credentials/drive-java-quickstart");

    /** Global instance of the {@link FileDataStoreFactory}. */
    private static FileDataStoreFactory DATA_STORE_FACTORY;

    /** Global instance of the JSON factory. */
    private static final JsonFactory JSON_FACTORY =
            JacksonFactory.getDefaultInstance();

    /** Global instance of the HTTP transport. */
    private static HttpTransport HTTP_TRANSPORT;

    private static Drive service = null;

    protected static String FILE_FIELDS = "id, name, createdTime, mimeType, trashed, permissions, parents, teamDrive";

    /**
     * Global instance of the scopes.
     *
     * If modifying these scopes, delete your previously saved credentials
     * at ~/.credentials/drive-java-quickstart
     */
    private static final List<String> SCOPES =
            Arrays.asList(DriveScopes.DRIVE);

    private String authFile;

    static {
        try {
            HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
            DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
        } catch (Throwable t) {
            t.printStackTrace();
            System.exit(1);
        }
    }

    public SOTeamDriveCreate(String authFile) {
        this.authFile = authFile;
    }

    /**
     * Creates an authorized Credential object.
     *
     * @return an authorized Credential object.
     * @throws IOException
     */
    public Credential authorize() throws IOException {
        GoogleCredential credential = GoogleCredential
                .fromStream(new FileInputStream(authFile))
                .createScoped(Arrays.asList(DriveScopes.DRIVE));
        return credential;
    }

    /**
     * Build and return an authorized Drive client service.
     *
     * @return an authorized Drive client service
     * @throws IOException
     */
    public Drive getDriveService() throws IOException {
        if (service == null) {
            Credential credential = authorize();
            service = new Drive.Builder(
                    HTTP_TRANSPORT, JSON_FACTORY, credential)
                            .setApplicationName(APPLICATION_NAME)
                            .build();
        }
        return service;
    }

    public static void main(String[] args) throws Exception {
        SOTeamDriveCreate createTeamDrive = new SOTeamDriveCreate("client_secrets.json");
        createTeamDrive.createTeamDrive();
    }

    public void createTeamDrive() throws Exception {
        TeamDrive teamDriveMetadata = new TeamDrive();
        teamDriveMetadata.setName("Team Drive created with Service Account");
        String requestId = UUID.randomUUID().toString();
        TeamDrive teamDrive = getDriveService().teamdrives().create(requestId, teamDriveMetadata).setFields(FILE_FIELDS).execute();
    }

}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <artifactId>so-team-drive-create</artifactId>
    <packaging>war</packaging>
    <name>SOTeamDriveCreate</name>
    <description>Google Service Account Team Drive creation</description>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <prerequisites>
        <maven>3.2.1</maven>
    </prerequisites>
    <properties>
        <maven-war-plugin.version>2.4</maven-war-plugin.version>
        <java.version>1.8</java.version>

        <google.http-client.version>1.23.0</google.http-client.version>
        <google.oauth-client.version>1.23.0</google.oauth-client.version>
        <google.api-client.version>1.23.0</google.api-client.version>
        <google-api-services.version>v3-rev119-1.23.0</google-api-services.version>
        <google-api-services-storage.version>v1-rev132-1.23.0</google-api-services-storage.version>

    </properties>

    <dependencies>
        <!-- Google Drive API. -->
        <dependency>
            <groupId>com.google.api-client</groupId>
            <artifactId>google-api-client</artifactId>
            <version>${google.api-client.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.oauth-client</groupId>
            <artifactId>google-oauth-client-jetty</artifactId>
            <version>${google.oauth-client.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-storage</artifactId>
            <version>${google-api-services-storage.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.http-client</groupId>
            <artifactId>google-http-client-jackson2</artifactId>
            <version>${google.http-client.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-drive</artifactId>
            <version>${google-api-services.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.api-client</groupId>
            <artifactId>google-api-client-assembly</artifactId>
            <version>${google.api-client.version}</version>
            <type>pom</type>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>${maven-war-plugin.version}</version>
                <configuration>
                    <warName>${project.name}</warName>
                    <source>${java-version}</source>
                    <target>${java-version}</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>clean</phase>
                        <goals>
                            <goal>run</goal>
                        </goals>
                        <configuration>
                            <target>
                                <echo>Here are some common goals for this project:</echo>
                                <echo>$ mvn clean compile</echo>
                                <echo>$ mvn exec:java -Dexec.mainClass=SOTeamDriveCreate</echo>
                            </target>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>1.2.1</version>
                <executions>
                    <execution>
                        <goals><goal>java</goal></goals>
                    </execution>
                </executions>
                <configuration>
                    <executable>java</executable>
                    <classpathScope>compile</classpathScope>
                    <mainClass>${exec.mainClass}</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

person EGHM    schedule 30.05.2018    source источник
comment
Это не отвечает на вопрос, поэтому я поставлю это как комментарий. Но я потратил около 10 часов на эту же проблему. Для моих целей я хотел, чтобы учетная запись службы создавала групповой диск для удобства. Но оказывается, что вы можете создать общий диск с личной учетной записью и просто пригласить адрес электронной почты служебной учетной записи. Я просто установил флажок, чтобы указать, что он не должен уведомлять пользователя. Он предупредит вас, что пользователь не входит в организацию (и это нормально). Но это сработало. Вы можете перечислить общий диск из учетной записи службы, чтобы затем получить к нему доступ по идентификатору.   -  person stuckj    schedule 09.07.2018
comment
Спасибо, застрял. Мы также ищем удобство. Мне нужно было создать 60 общих дисков (в следующем году их будет еще больше), поэтому я создал их с помощью инструмента командной строки под личной учетной записью и добавил служебные учетные записи. Надеемся на более интегрированное решение в следующем году.   -  person EGHM    schedule 10.07.2018


Ответы (1)


Товарищ по команде решил нашу проблему.

  • Во-первых, в консоли администратора предприятия нам нужно было настроить у нашего клиента доступ ко всему домену.
  • Затем мы использовали createCredentialForServiceAccountImpersonateUser из https://googleapis.dev/java/google-api-client/latest/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.html, который использует файл P12File для создания GoogleCredential. Первоначально мы пытались использовать файл json, который работал для всего, ЗА ИСКЛЮЧЕНИЕМ создания нового общего диска, только версия P12File позволяет нам создать новый общий диск.
person EGHM    schedule 31.05.2019