web-dev-qa-db-fra.com

Authentifiez-vous par programme auprès de Google avec OAuth2

Comment puis-je m'authentifier par programme auprès de Google? Maintenant que ClientLogin ( https://developers.google.com/accounts/docs/AuthForInstalledApps ) est obsolète, comment pouvons-nous effectuer une authentification programmatique auprès de Google avec OAuth2?

Avec ClientLogin, nous pourrions effectuer une publication sur https://www.google.com/accounts/ClientLogin avec les paramètres de messagerie et de mot de passe et obtenir le jeton d'authentification.

Avec OAuth2, je ne trouve pas de solution!

Mon application est un processus d'arrière-plan Java. J'ai vu, en suivant ce lien: developers.google.com/accounts/docs/OAuth2InstalledApp#refresh, comment obtenir un nouveau jeton d'accès à l'aide d'un jeton actualisé.

Le problème est que je ne trouve pas un exemple Java sur la façon d'instancier un objet Analytics (par exemple) pour effectuer une requête lorsque j'ai un nouveau jeton d'accès valide

C'est mon code qui retourne un 401 informations d'identification non valides lors de l'appel du "execute ()":

public class Test {

static final String client_id = "MY_CLIENT_ID";
static final String client_secret = "MY_SECRET";
static final String appName = "MY_APP";

private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final JsonFactory JSON_FACTORY = new JacksonFactory();

static String access_token = "xxxx";
static String refreshToken = "yyyyy";

public static void main (String args[]){

    try {

        GoogleCredential credential = 
            new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setClientSecrets(client_id, client_secret).build();
        credential.setAccessToken(access_token);
        credential.setRefreshToken(refreshToken);
        //GoogleCredential
        Analytics analytics = Analytics.builder(HTTP_TRANSPORT, JSON_FACTORY)
            .setApplicationName(appName)
            .setHttpRequestInitializer(credential)
            .build();

        Accounts accounts = analytics.management().accounts().list().execute();
    } catch (Exception e) {
        e.printStackTrace();
    } 
}

Quel est le problème?

26
Andrea Zonzin

Vérifiez le flux OAuth 2 pour l'application installée:

https://developers.google.com/accounts/docs/OAuth2InstalledApp

Il nécessite toujours que l'utilisateur s'authentifie avec un navigateur la première fois, mais vous pouvez ensuite stocker le jeton d'actualisation et l'utiliser pour les demandes suivantes.

Pour des solutions alternatives, vérifiez le flux de périphériques ou les comptes de service, ils sont expliqués dans le même ensemble de documentation.

16

J'ai trouvé que le client Google Java Java était trop complexe et mal documenté. Voici un servlet simple et simple exemple avec Google Oauth2. Pour un processus d'arrière-plan, vous devrez demander access_type = offline. Comme d'autres l'ont mentionné, vous devez demander à l'utilisateur une autorisation unique. Après cela, vous pouvez demander des jetons d'actualisation car les jetons Google expirent dans une heure.

15
Andrew

Bien que j'apprécie que l'OP visait à l'origine l'approche OAuth2InstalledApp , je voudrais souligner une solution de travail utilisant l'approche OAuth2WebServer . Ils ne diffèrent pas de manière significative et cela a fonctionné pour moi. J'ai trouvé que la bibliothèque google OAuth est assez bonne car elle gérera la plupart des danses OAuth pour vous et facilite le rafraîchissement du jeton d'accès) La solution ci-dessous dépend de l'utilisation d'un jeton de rafraîchissement pré-obtenu.

Comme l'indique la réponse acceptée, pour faire fonctionner l'authentification OAuth (même pour un processus d'arrière-plan Java)) où la demande repose sur l'accès aux données utilisateur

, l'utilisateur doit s'authentifier avec un navigateur la première fois, mais vous pouvez ensuite stocker le jeton d'actualisation et l'utiliser pour les demandes suivantes.

D'après les commentaires précédents du PO, je vois ce qui suit

J'ai donc suivi OAuth2 pour les applications de serveur Web (ici l'accès hors ligne est documenté) mais j'ai toujours des problèmes.
1) J'effectue la première demande via un navigateur et j'obtiens un code d'authentification pour un accès hors ligne
2) J'effectue un Java poste du code d'authentification et j'obtiens un jeton d'accès et un jeton d'actualisation

L'approche que j'ai utilisée ressemble plus à

1) J'effectue la première demande via un navigateur et j'obtiens le jeton d'actualisation pour un accès hors ligne
2) Dans Java je fournis le jeton d'actualisation à la bibliothèque et la bibliothèque obtiendra le jeton d'accès, etc.

en particulier, en utilisant google-api-Java-client library le code est assez simple et notez que je n'ai pas défini de jeton d'accès comme l'OP l'a fait, car j'appelle credential.refreshToken(); autre part. (Je vérifie si j'ai déjà un jeton d'accès valide et si ce n'est pas le cas, actualiser l'appel avant l'appel de l'API)

  private Credential generateCredentialWithUserApprovedToken() throws IOException,
      GeneralSecurityException {
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    InputStreamReader inputStreamReader =
        new InputStreamReader(jsonFileResourceForClient.getInputStream());
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(jsonFactory, inputStreamReader);
    return new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
        .setClientSecrets(clientSecrets).build().setRefreshToken(REFRESH_TOKEN);
  }

Notez que cela couvre l'étape 2 de mon approche et le REFRESH_TOKEN mentionné à l'étape 1 peut être obtenu comme expliqué ci-dessous.

Il y a d'abord une configuration préalable d'une application Web création d'un OAuth 2.0 ID client sur le console Google pour les informations d'identification où vous vous retrouvez avec un fichier json téléchargé qui sera lu dans l'objet GoogleClientSecrets.

c'est à dire.

enter image description here

Assurez-vous d'ajouter l'URI de rappel de Google Playground dans les URI de redirection autorisés

enter image description here

Ensuite, vous avez votre identifiant client et le secret client prêt pour le terrain de jeu et vous pouvez également télécharger le json que vous pouvez insérer dans votre code Java.

enter image description here

Le REFRESH_TOKEN s'obtient en envoyant une demande au google oauth aire de jeux avec la configuration suivante. Notez qu'avant l'étape 1 et en sélectionnant votre portée, vous devez accéder aux paramètres pour vérifiez que vous fournissez vos propres informations d'identification et ajoutez votre identifiant client et votre secret juste en dessous

enter image description here

Notez que le type d'accès est hors ligne, ce qui correspond à this .

Il y a aussi une belle explication sur la récupération du jeton d'actualisation ici https://www.youtube.com/watch?v=hfWe1gPCnzc

C'est suffisant pour démarrer et c'est une configuration unique!

En ce qui concerne les jetons de rafraîchissement, vous devez être conscient de leur cycle de vie, comme indiqué dans la documentation ici

Dans le oauthplayground, vous verrez ceci

enter image description here

mais au point 4 de la documentation ici il dit ceci

enter image description here

Hmmm.

Aussi pour référence voir Comment puis-je autoriser une application (web ou installée) sans intervention de l'utilisateur? (Canonique?)

10
Matt C

Pour les applications qui s'authentifient en leur nom (c'est-à-dire auprès d'une autre application, traditionnellement en se connectant à un compte de rôle à l'aide d'un mot de passe partagé), l'alternative OAuth2 à ClientLogin proposée par Google est les comptes de service:

https://developers.google.com/accounts/docs/OAuth2ServiceAccount

0
breno