Jean-Christophe Blanchard Jean-Christophe Blanchard - 3 months ago 34
Java Question

Get Google authorization from java program open browser for asking already given permission

In order for a java program to access my google drive I need to create an oauth2.Credential using a json credential file (see https://console.developers.google.com) for getting an access token.

Credentials with client id

The problem is when I create the Credential java instance the java program open Internet Explorer and ask permission for Drive.

Credential credential = new AuthorizationCodeInstalledApp(flow
, new LocalServerReceiver())
.authorize("user")
;


Program automatically opens browser and ask permission

If I click button "allow" , Credential is created and I get a token.

System.out.println("token" + credential.getAccessToken());


Browser after clicked on Allow

Java console view in Eclipse : token get

The problem is that this java program will be a batch program so we can't ask the batch to click on a button.

Furthermore in https://security.google.com/settings/security/permissions?pli=1 my Drive has already given access to my application (application name is GoogleTest) ...

application already granted

Do you know how to get the credential without java program open browser for asking permission ?
Thank you

Here the full code :

public static void getToken () {
HttpTransport httpTransport ;
InputStream inputStream;
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
List<String> scope = Arrays.asList(DriveScopes.DRIVE);
inputStream = new FileInputStream("C:/dev/ws/mainAzure/GoogleTest/res/client_secret_jcb_inst.json");
InputStreamReader reader = new InputStreamReader(inputStream);
clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,reader);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport
, JSON_FACTORY
,clientSecrets
, scope)
.setAccessType("offline")
.setApprovalPrompt("force")
.build();

//Browser open when there is new AuthorizationCodeInstalledApp(...)
Credential credential = new AuthorizationCodeInstalledApp(flow
, new LocalServerReceiver())
.authorize("user")
;
System.out.println("token" + credential.getAccessToken());
} catch (Exception e) {
e.printStackTrace();
}
}

Answer

After some help (thank you Harold) I could find the solution: One need to define a datastorefactory, elsewhere the refreshToken is not stored in a file and Google via Internet browser as for permission each time. So : Add :

dataStoreFactory = new FileDataStoreFactory(new File("C:/dev/ws/mainAzure/GoogleTest/res"));

and :

 GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
            httpTransport
             , JSON_FACTORY
             ,clientSecrets
             , scope)
             .setAccessType("offline")
             .setApprovalPrompt("force")
             .build(); 

become :

            flow = new GoogleAuthorizationCodeFlow.Builder(
                httpTransport
                 , JSON_FACTORY
                 ,clientSecrets
                 , scope)                     
                 .setAccessType("offline")
                 .setDataStoreFactory(dataStoreFactory)
                 .setApprovalPrompt("force")                 
                 .build();

Furthermore to have an access non limited to 1 hour, one need to refresh the token :

credential.refreshToken() ;