如何解决 Google Service Account Team Drive creation insufficientFilePermissions 错误?
How to resolve Google Service Account Team Drive creation error of insufficientFilePermissions?
我正在尝试使用我的服务帐户创建 Google Team Drive,但收到 insufficientFilePermissions 错误。有谁知道如何使用服务帐户创建 Google Team Drive,或者可以确定我在这里做错了什么?
为了便于使用,我创建了一个 github 项目,其中包含此处提供的文件。 https://gitlab.com/eghm-lab/Whosebug-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
文件权限不足错误:
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.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.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>
一位队友解决了我们的问题。
- 首先,我们需要在企业管理控制台上设置我们的客户端具有全域访问权限。
- 然后我们使用来自 https://googleapis.dev/java/google-api-client/latest/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.html 的 createCredentialForServiceAccountImpersonateUser,它使用 P12File 创建 GoogleCredential。最初我们尝试使用 json 文件,它适用于所有内容,除了创建一个新的团队驱动器,只有 P12File 版本允许我们创建一个新的团队驱动器。
我正在尝试使用我的服务帐户创建 Google Team Drive,但收到 insufficientFilePermissions 错误。有谁知道如何使用服务帐户创建 Google Team Drive,或者可以确定我在这里做错了什么?
为了便于使用,我创建了一个 github 项目,其中包含此处提供的文件。 https://gitlab.com/eghm-lab/Whosebug-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
文件权限不足错误:
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.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.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>
一位队友解决了我们的问题。
- 首先,我们需要在企业管理控制台上设置我们的客户端具有全域访问权限。
- 然后我们使用来自 https://googleapis.dev/java/google-api-client/latest/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.html 的 createCredentialForServiceAccountImpersonateUser,它使用 P12File 创建 GoogleCredential。最初我们尝试使用 json 文件,它适用于所有内容,除了创建一个新的团队驱动器,只有 P12File 版本允许我们创建一个新的团队驱动器。