2017-06-07 3 views
3

J'ai créé une application Java qui synchronise MS Active Directory avec Google Groupes. C'est une application non-interactive qui suppose d'être exécutée par le cronjob pendant la nuit. Cela fonctionne parfaitement sur mon ordinateur portable (environnement DEV). Mon problème est que la première fois, il affiche la fenêtre du navigateur avec la boîte de dialogue demandant d'autoriser l'accès à l'API Google. Après avoir cliqué sur le bouton "Autoriser", je continue heureusement jusqu'à la fin. Maintenant je dois le déplacer vers un serveur de production qui exécute CentOS et qui n'a pas de navigateur. Quand je lance mon application dans cet environnement, il imprime le message suivant:Autorisation non interactive avec Google OAuth2

Please open the following address in your browser: 
https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=520105804541-c7d7bfki88qr8dbkv6oahp22i3oq1jq0.apps.googleusercontent.com&redirect_uri=http://localhost:50089/Callback&response_type=code&scope=https://www.googleapis.com/auth/admin.directory.group.member%20https://www.googleapis.com/auth/admin.directory.orgunit%20https://www.googleapis.com/auth/admin.directory.device.mobile.action%20https://www.googleapis.com/auth/admin.directory.orgunit.readonly%20https://www.googleapis.com/auth/admin.directory.userschema%20https://www.googleapis.com/auth/admin.directory.device.chromeos%20https://www.googleapis.com/auth/admin.directory.notifications%20https://www.googleapis.com/auth/admin.directory.device.chromeos.readonly%20https://www.googleapis.com/auth/admin.directory.device.mobile%20https://www.googleapis.com/auth/admin.directory.group.readonly%20https://www.googleapis.com/auth/admin.directory.group.member.readonly%20https://www.googleapis.com/auth/admin.directory.userschema.readonly%20https://www.googleapis.com/auth/admin.directory.user.alias%20https://www.googleapis.com/auth/admin.directory.user.security%20https://www.googleapis.com/auth/admin.directory.device.mobile.readonly%20https://www.googleapis.com/auth/admin.directory.user%20https://www.googleapis.com/auth/admin.directory.user.readonly%20https://www.googleapis.com/auth/admin.directory.user.alias.readonly%20https://www.googleapis.com/auth/admin.directory.group%20https://www.googleapis.com/auth/apps.groups.settings 

Il n'y a pas de navigateur sur cette machine mais si je tente de l'exécuter sur une autre case, je reçois une erreur 400 - demande non valide. La raison est claire, car il redirige vers localhost: 50089 et personne n'écoute sur ce port sur une autre machine. En parcourant les multiples documents et exemples sur developers.google.com J'ai trouvé un moyen de contourner la boîte de dialogue en créant le compte de service et en générant une clé primaire pour cela.

try { 
     GoogleCredential cr = GoogleCredential 
      .fromStream(new FileInputStream(keyFile)) 
      .createScoped(SCOPES); 
     Directory directory = new Directory.Builder(httpTransport, jsonFactory, cr) 
.setApplicationName(config.getProperty("google.application.name")).build(); 
    } catch (IOException ex) { 
     LOG.error("Failed to establish access credentials : ", ex.getMessage()); 
    } 

Il ne lit la clé et ne crée instance Directory, mais toute demande à elle aboutit à 403 code de réponse

{ "code": 403, "erreurs": [{ "domain" : "global", "message": "Non autorisé à accéder à cette ressource/API", "raison": "interdit"
}], "message": "Non autorisé à accéder à cette ressource/API"} "

Mais j'ai déléguée al l les privilèges de ce compte sur le compte de service. Je ne sais pas ce que je peux faire d'autre. Si quelqu'un peut m'aider à sortir de cette confiture, je l'apprécie grandement.

Répondre

3

J'ai trouvé une solution. Le problème est que la clé JSON générée par Google ne définit pas l'utilisateur du compte de service. Vous devez le faire manuellement comme ceci:

 GoogleCredential cr = GoogleCredential 
      .fromStream(new FileInputStream(keyFile)) 
      .createScoped(SCOPES); 
     GoogleCredential.Builder builder = new GoogleCredential.Builder() 
      .setTransport(httpTransport) 
      .setJsonFactory(jsonFactory) 
      .setServiceAccountScopes(SCOPES) 
      .setServiceAccountId(cr.getServiceAccountId()) 
      .setServiceAccountPrivateKey(cr.getServiceAccountPrivateKey()) 
      .setServiceAccountPrivateKeyId(cr.getServiceAccountPrivateKeyId()) 
      .setTokenServerEncodedUrl(cr.getTokenServerEncodedUrl()) 
      .setServiceAccountUser(user); 
     Directory directory = new Directory.Builder(
       httpTransport, jsonFactory, builder.build()) 
      .setApplicationName(config.getProperty("google.application.name")).build(); 
+0

vous êtes un épargnant de vie! google documentation suce, et c'est le seul exemple qui vient de fonctionner. – Alex