Sandeep Chatterjee
Sandeep Chatterjee

Reputation: 3249

com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden

I am trying to upload a text file to my Google Drive account. No matter what, I always encounter an com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden

Stacktrace:

Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
{
  "code" : 403,
  "errors" : [ {
    "domain" : "global",
    "message" : "Forbidden",
    "reason" : "forbidden"
  } ],
  "message" : "Forbidden"
}
    at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:145)
    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.executeUnparsed(AbstractGoogleClientRequest.java:423)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
    at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
    at chatterjee.sandeep.javabase.miscellaneous.DriveCommandLine.main(DriveCommandLine.java:69)

Here is line 69 of DriveCommandLine.java

File file = service.files().insert(body, mediaContent).execute();

Complete Code:

import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.FileContent;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class DriveCommandLine {

    private static String CLIENT_ID = "CLIENT_ID";
    private static String CLIENT_SECRET = "CLIENT_SECRET";

    private static String REDIRECT_URI = "REDIRECT_URI";

    public static void main(String[] args) throws IOException {
        HttpTransport httpTransport = new NetHttpTransport();
        JsonFactory jsonFactory = new JacksonFactory();

        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, jsonFactory, CLIENT_ID, CLIENT_SECRET,
        Arrays.asList(DriveScopes.DRIVE_FILE)).setAccessType("online")
        .setApprovalPrompt("auto").build();

        String url = flow.newAuthorizationUrl().setRedirectUri(REDIRECT_URI)
        .build();
        System.out
        .println("Please open the following URL in your browser then type the authorization code:");
        System.out.println("  " + url);
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String code = br.readLine();

        GoogleTokenResponse response = flow.newTokenRequest(code)
        .setRedirectUri(REDIRECT_URI).execute();
        GoogleCredential credential = new GoogleCredential()
        .setFromTokenResponse(response);

        // Create a new authorized API client
        Drive service = new Drive.Builder(httpTransport, jsonFactory,
        credential).build();

        // Insert a file
        File body = new File();
        body.setTitle("My document");
        body.setDescription("A test document");
        body.setMimeType("text/plain");

        java.io.File fileContent = new java.io.File(
        "/path/to/TextFile.txt");
        FileContent mediaContent = new FileContent("text/plain", fileContent);

        File file = service.files().insert(body, mediaContent).execute();
        System.out.println("File ID: " + file.getId());
    }
}

I have the following jars in my project build path:

commons-logging-1.1.1.jar
google-api-client-1.18.0-rc.jar
google-api-client-android-1.18.0-rc.jar
google-api-client-appengine-1.18.0-rc.jar
google-api-client-gson-1.18.0-rc.jar
google-api-client-jackson2-1.18.0-rc.jar
google-api-client-java6-1.18.0-rc.jar
google-api-client-servlet-1.18.0-rc.jar
google-api-services-drive-v1-rev123-1.18.0-rc.jar
google-http-client-1.18.0-rc.jar
google-http-client-android-1.18.0-rc.jar
google-http-client-appengine-1.18.0-rc.jar
google-http-client-gson-1.18.0-rc.jar
google-http-client-jackson2-1.18.0-rc.jar
google-http-client-jdo-1.18.0-rc.jar
google-oauth-client-1.18.0-rc.jar
google-oauth-client-appengine-1.18.0-rc.jar
google-oauth-client-java6-1.18.0-rc.jar
google-oauth-client-jetty-1.18.0-rc.jar
google-oauth-client-servlet-1.18.0-rc.jar
gson-2.1.jar
httpclient-4.0.3.jar
httpcore-4.0.1_1.jar
jackson-core-2.1.3.jar
jdo2-api-2.3-eb.jar
jetty-util-6.1.26.jar
jsr305-1.3.9.jar
transaction-api-1.1-rev-1.jar

At present I have two projects set up with Drive API enabled.

enter image description here

Now where do I properly set up the permissions to resolve this issue?

Also, what am I doing wrong here?

Upvotes: 16

Views: 34782

Answers (9)

N J
N J

Reputation: 1

  1. Make sure to use DriveScopes.DRIVE for allowed SCOPE: private static final List SCOPES = Collections.singletonList(DriveScopes.DRIVE);

  2. Make sure to reset token directory path as below:

     GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
             HTTP_TRANSPORT,
             JSON_FACTORY, clientSecrets, SCOPES)
             //.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
             .setDataStoreFactory(new MemoryDataStoreFactory())
             .setAccessType("offline")
             .build();
    

Othewise it will always use the cached version.

Upvotes: 0

Abhinav Saxena
Abhinav Saxena

Reputation: 3904

For me issue was SCOPES, it was set to SheetsScopes.SPREADSHEETS_READONLY.

So I changed it to SheetsScopes.SPREADSHEETS, deleted the Token folder in the project directory and run the program again and it worked.

Upvotes: 2

Vitali Rahin
Vitali Rahin

Reputation: 61

This issue happened when you change SCOPE and proceed to work with the old token. Just remove StoredCredential file.Idea

Upvotes: 6

Yster
Yster

Reputation: 3305

After a long time searching, I found this answer hidden in the search engine:

Change the line where you define scopes to:

private static final List<String> SCOPES = Arrays.asList(GmailScopes.MAIL_GOOGLE_COM);

https://stackoverflow.com/a/38599382/1317559

Upvotes: 4

Cesarov
Cesarov

Reputation: 11

I had the same problem but in my case resolve this with:

private static final List<String> SCOPES =
        Arrays.asList(DriveScopes.DRIVE);

from DriveScopes

and also create a new directory

private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".credentials/2/drive-java-quickstart.json");

and i solved the problem

Upvotes: 1

Suraj Muraleedharan
Suraj Muraleedharan

Reputation: 1344

I had the same issue, I did the following change and it resolved the issue

1) Added SheetsScopes.DRIVE to the scopes to be given in authorize()

private static final List<String> SCOPES =
            Arrays.asList(SheetsScopes.SPREADSHEETS,SheetsScopes.DRIVE);

2) Created a new directory, so that next time I run it, it will authenticate and save the credential to the newly created directory

private static final java.io.File DATA_STORE_DIR = new java.io.File(
        System.getProperty("user.home"), ".credentials/2/sheets.googleapis.com-java-quickstart.json");

Upvotes: 8

SpyZip
SpyZip

Reputation: 5540

For me the problem was that the url was http... and it should be https...

Upvotes: 0

user5538597
user5538597

Reputation: 21

I just had this problem and it is likely that you have created the credential file using a scope that does not allow inserting a file. Remove the credential file and re-run.

Upvotes: 2

Roman
Roman

Reputation: 2003

Been having same quota errors for months. Tried everything. It looks like problem on Google side. Among all google products, Calendar API does not have any way to support their team. If anyone knows or have been able to contact Google team about Calendar API, let us know!

Upvotes: 1

Related Questions