web-dev-qa-db-fra.com

API Google OAuth2, compte de service, "error": "invalid_grant"

J'essaie d'utiliser un compte de service pour synchroniser les calendriers du logiciel Dynamics CRM vers Google . Pendant ce temps, je manquais de documentation sur Google API pour .net, notamment en ce qui concerne l'autorisation. La plupart des exemples de Google ne peuvent même pas être compilés à cause des bibliothèques et des classes obsolètes utilisées.

J'ai donc trouvé un exemple d'interné et recevoir une erreur. Quelqu'un pourrait-il s'il vous plaît regarder sur mon échantillon et dire ce que je fais mal?

Étapes préparatoires:

  1. J'ai créé un projet dans mon compte Google privé.
  2. Dans la console du développeur de projet, sous APIS & AUTH -> Informations d'identification, j'ai généré un compte de service. Puis cliqué sur "Générer la clé P12" et téléchargé le fichier .p12.
  3. Sous APIS & AUTH -> API, "API du calendrier" activé

Ensuite, créé l’application de la console et a réussi à installer les packages de nuget OAuth et Calendar. Il y a:

  1. Bibliothèque de clients Auth des API Google, Google.Apis.Auth 1.8.1
  2. Bibliothèque cliente des API Google, Google.Apis 1.8.1
  3. Bibliothèque de clients principaux API Google, Id: Google.Apis.Core 1.8.1
  4. Google.APIs.Calendar.v3 Bibliothèque de clients, Google.Apis.Calendar.V3 1.8.1.860

Il existe un code trouvé et adapté à mes besoins:

using System;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Calendar.v3;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;

namespace CrmToGoogleCalendar
{
    class Program
    {

        static void Connect()
        {
            var certificate = new X509Certificate2("My Project-ee7facaa2bb1.p12", "notasecret", X509KeyStorageFlags.Exportable);


            var serviceAccountEmail = "506310960175-q2k8hjl141bml57ikufinsh6n8qiu93b@developer.gserviceaccount.com";
            var userAccountEmail = "<my email>@gmail.com";
            var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail) 
                {
                    User = userAccountEmail,
                    Scopes = new[] { CalendarService.Scope.Calendar }
                }
                .FromCertificate(certificate));

            var service = new CalendarService(new BaseClientService.Initializer()
            {
                ApplicationName = "Test calendar sync app",
                HttpClientInitializer = credential

            });

            var calList = service.CalendarList.List().Execute().Items;


            foreach (var cal in calList)
            {
                Console.WriteLine(cal.Id);
            }
        }


        static void Main(string[] args)
        {
            Connect();
        }
    }
}

La communication avec Google API que je vois dans l'application et Fiddler est:

Demande :

Hôte: comptes HTTPS.google.com, URL:/o/oauth2/token
Assertion: longue chaîne binaire
grant_type: urn: ietf: params: oauth: grant-type: jwt-bearer

Réponse:

HTTP/1.1 400 Requête incorrecte Content-Type: application/json Cache-Control: no-cache, no-store, max-age = 0, doit revalider Pragma: no-cache Expire le: vendredi, 1er janvier 1990, 00:00:00 GMT Date: le jeudi, 24 juillet 2014 06:12:18 Options de type de contenu GMT X: Options de X-Frame de nosniff: SAMEORIGIN Protection X-XSS: 1; mode = block Serveur: GSE Alternate-Protocol: 443: Quic Transfer-Encoding: chunked

1f {"erreur": "invalid_grant"} 0

Fiddler screenshot

S'il vous plaît aider et merci d'avance!

12
Dimitry

j'avais le même problème, ça fonctionnait bien sur un serveur distant, mais sur le serveur local, j'ai eu cette erreur, longue histoire après des heures de maux de tête, j'ai découvert que le problème venait de mon horloge système, il suffit de suivre ces étapes 

1. Cliquez sur l'horloge de votre système

  • Cela fera apparaître le calendrier et l'heure 

2. Cliquez sur Modifier les paramètres de date et d'heure ...

  • La boîte de dialogue Date et heure apparaîtra

3. Cliquez sur l'onglet Heure Internet

4. Cliquez sur Modifier les paramètres

  • La boîte de dialogue Internet Time Settings apparaît.

puis enfin mettre à jour votre horloge avec l'un des serveurs de temps

0
Abolfazl

Je ne suis pas vraiment sûr de ce qui ne va pas dans votre code. Je pense que cela explique comment vous chargez le fichier de clé. Cela pourrait également être le fait que vous n'avez pas besoin d'envoyer User avec ServiceAccountCredential puisque le compte de service est l'utilisateur auquel vous vous connectez. Je ne sais pas pourquoi vous envoyez un email à quelqu'un par Gmail. 

using Google.Apis.Auth.OAuth2;
using System.Security.Cryptography.X509Certificates;
using Google.Apis.Calendar.v3;
namespace GoogleAnalytics.Service.Account
{
    class Program
    {
        static void Main(string[] args)
        {
            //Install-Package Google.Apis.Calendar.v3
            string serviceAccountEmail = "1046123799103-6v9cj8jbub068jgmss54m9gkuk4q2qu8@developer.gserviceaccount.com";
            var certificate = new X509Certificate2(@"C:\Users\HP_User\Documents\GitHub\Google-Analytics-dotnet-ServiceAccount\GoogleAnalytics.Service.Account\Diamto Test Everything Project-bc63fd995bd7.p12", "notasecret", X509KeyStorageFlags.Exportable);

            ServiceAccountCredential credential = new ServiceAccountCredential(
                   new ServiceAccountCredential.Initializer(serviceAccountEmail)
                   {
                       Scopes = new[] { CalendarService.Scope.Calendar }
                   }.FromCertificate(certificate));

            // Create the service.
            var service = new CalendarService(new CalendarService.Initializer()
            {
                HttpClientInitializer = credential,
                ApplicationName = "CalendarService API Sample",
            });

            // define the new Calendar
            Google.Apis.Calendar.v3.Data.Calendar calendar = new Google.Apis.Calendar.v3.Data.Calendar();
            calendar.Description = "New Calendar";
            calendar.Summary = "New Calendar Summary";
            // Insert the Calendar
            service.Calendars.Insert(calendar).Execute();
            // List The Calendar
            var calList = service.CalendarList.List().Execute().Items;

        }
    }
}

Ce code est testé, il vous montre comment créer le calendrier initial pour le compte de service. Sans créer un calendrier, il renverrait 0 calendrier, vous devez d'abord en créer un.

0
DaImTo