webentwicklung-frage-antwort-db.com.de

Google.GData.Client.GDataRequestException - Die Authentifizierung schlägt in altem Code plötzlich fehl

Ich versuche plötzlich, die folgende Ausnahme zu erhalten, wenn ich mich auf Google-Laufwerk authentifizieren und auf eine Tabelle zugreifen möchte:

Nicht behandelte Ausnahme: Google.GData.Client.GDataRequestException: Die Ausführung der automatischen Hentication-Anforderung hat unerwartet zurückgegeben Ergebnis: 404 at Google.GData.Client.Utilities.getAuthException (TokenCollection-Token, Htt pWebResponse-Antwort) at Google.GData.Client.Utilities.QueryClientLoginToken (GDataCredentials gc, Sende-Dienstname, Zeichenfolge Anwendungsname, Boolean fUseKeepAlive, IWebProxy-Proxy yServer, Uri clientLoginHandler) bei Google.GData.Client.GDataGAuthRequest.QueryAuthToken (GDataCredentials gc) bei Google.GData.Client.GDataGAuthRequest.EnsureCredentials () bei Google.GData.Client.GDataRequest.EnsureWebRequest () bei Google.GData.Client.GDataGAuthRequest.EnsureWebRequest () bei Google.GData.Client.GDataRequest.Execute () bei Google.GData.Client.GDataGAuthRequest.Execute (Int32 retryCounter) bei Google.GData.Client.GDataGAuthRequest.Execute () bei Google.GData.Client.Service.Query (Uri queryUri, DateTime ifModifiedSince, String etag, Int64 & contentLength) bei Google.GData.Client.Service.Query (FeedQuery feedQuery) bei Google.GData.Documents.DocumentsService.Query (DocumentsListQuery feedQuery) bei GoogleLogger.GoogleService.getLastXECLogRows (String ordnername, String dateiname, Int32-Zeilen)

Dies ist ein Code, der seit zwei Jahren ohne Probleme läuft. Ich dachte zuerst, dass ich Zugriffsberechtigungen für mein Produktionssystem verloren haben könnte, aber das Google-Laufwerk wird in meinem Webbrowser einwandfrei geladen. Ich habe es auf mehreren anderen Systemen ausprobiert und bekomme dasselbe. 

Haben sie heute etwas in der Google API geändert? Das kann kein Zufall sein!

15
Molecool

Google hat seine ältere Authentifizierungs-API zurückgezogen. Stattdessen sollte OAuth 2.0 verwendet werden.

Ich habe zu viel Zeit darauf verwendet, um herauszufinden, wie die neuere Auth-API verwendet wird, wenn ältere und ältere GData-API hier und dort Informationen aus dem Internet holt .. Ich entschied mich, alle Details mit Screenshots zu teilen, um Zeit zu sparen.

  1. Gehen Sie zu https://console.developers.google.com/project

  2. Drücken Sie die Create Project-Taste

enter image description here

  1. Projekt erstellen Geben Sie einen Namen ein.

enter image description here

  1. Gehen Sie zu API & Auth> Credentials und drücken Sie die Create new Client ID-Taste. Es erstellt automatisch einen JSON-Schlüssel für Sie - ignorieren Sie dies.

enter image description here

  1. Schlagen Sie Generate new P12 key

enter image description here

  1. Der Dateidownload wird automatisch gestartet. Merken Sie sich das Passwort, Sie benötigen es, um die gerade heruntergeladene Datei zu öffnen.

enter image description here

  1. Benennen Sie die heruntergeladene Datei in Key.p12 um und fügen Sie sie Ihrer Lösung hinzu. Stellen Sie sicher, dass Sie Build Action und Copy to Output Directory entsprechend eingestellt haben.

enter image description here

  1. Installieren Sie Google API Auth mit Nuget. Geben Sie Folgendes in die Package Manager Console ein

    Install-Package Google.Apis.Auth
    

enter image description here

  1. Kopieren Sie die E-Mail-Adresse des Dienstkontos, die in Schritt 4 generiert wurde.

enter image description here

  1. Erteilen Sie diesem Nutzer die entsprechende Berechtigung in Ihrer Google-Tabelle.

  2. Verwenden Sie den folgenden Code, um die Kalkulationstabelle abzufragen. Ersetzen Sie die URL-Adresse der E-Mail- und Google-Tabelle im nachstehenden Code.

    const string ServiceAccountEmail = "[email protected]ount.com";
    
    var certificate = new X509Certificate2("Key.p12", "notasecret", X509KeyStorageFlags.Exportable);
    
    var serviceAccountCredentialInitializer = 
        new ServiceAccountCredential.Initializer(ServiceAccountEmail)
        {
            Scopes = new[] { "https://spreadsheets.google.com/feeds" }
        }.FromCertificate(certificate);
    
    var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
    
    if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
        throw new InvalidOperationException("Access token request failed.");
    
    var requestFactory = new GDataRequestFactory(null);
    requestFactory.CustomHeaders.Add("Authorization: Bearer " + credential.Token.AccessToken);
    
    var service = new SpreadsheetsService(null) { RequestFactory = requestFactory };
    
    var query = new ListQuery("https://spreadsheets.google.com/feeds/list/0ApZkobM61WIrdGRYshh345523VNsLWc/1/private/full");
    var feed = service.Query(query);
    
    var rows = feed.Entries
        .Cast<ListEntry>()
        .Select(arg =>
            new
            {
                Field0 = arg.Elements[0].Value,
                Field1 = arg.Elements[1].Value
            })
        .ToList();
    
33
Alex Aza

Es ist mir gelungen, dieses Problem zu lösen, indem diese Lösung mit dem Dienstkonto mit oAuth2.0 verwendet wurde Zugriff auf ältere GData-APIs (Spreadsheet-API) mit OAuth 2 und einem Dienstkonto

Die Lösung: 1. Erstellen Sie ein Projekt und ein Google-Dienstkonto in https://console.developers.google.com/project .

  1. Generieren Sie Ihren p12-Schlüssel.
  2. Erlauben Sie APIs in der Entwicklerkonsole, die Sie verwenden möchten (grundsätzlich werden wir alte APIs verwenden, sodass Sie diesen Schritt überspringen können, aber nur für den Fall).
  3. Verwenden Sie den folgenden Code (.NET Framework 4.5!)
  4. Vergessen Sie auch nicht, "[email protected]developer.gserviceaccount.com" Zugriff auf Ihr Tabellendokument zu gewähren, wenn Sie Berechtigungen für normale Benutzer erteilen, indem Sie auf Freigeben klicken.

Code:

using System.Security.Cryptography.X509Certificates;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;
using Google.Apis.Auth.OAuth2;

string keyFilePath = @"C:\key.p12";    // found in developer console
string serviceAccountEmail = "[email protected]";   // found in developer console
var certificate = new X509Certificate2(keyFilePath, "notasecret", X509KeyStorageFlags.Exportable);

ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail) //create credential using certificate
        {
            Scopes = new[] { "https://spreadsheets.google.com/feeds/" } //this scopr is for spreadsheets, check google scope FAQ for others
        }.FromCertificate(certificate));

credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Wait(); //request token

var requestFactory = new GDataRequestFactory("Some Name"); 
requestFactory.CustomHeaders.Add(string.Format("Authorization: Bearer {0}", credential.Token.AccessToken));

SpreadsheetsService myService = new SpreadsheetsService("You App Name"); //create your old service
myService.RequestFactory = requestFactory; //add new request factory to your old service

SpreadsheetQuery query = new SpreadsheetQuery(); //do the job as you done it before
SpreadsheetFeed feed = myService.Query(query);
5
Many More

Okay, ich habe es herausgefunden. Schrittweise Anweisungen wie folgt - siehe auch den unten angegebenen Code. Zu Ihrer Information, dies läuft in .Net 3.5 und im Gegensatz zu der zuvor angebotenen Lösung gibt es keine neuen Abhängigkeiten. Sie sollten in kürzester Zeit einsatzbereit sein.

  1. Wenn Sie Ihre OAuth 2.0-Anmeldeinformationen noch nicht erstellt haben - ich gehe davon aus, dass Sie bereits wissen, wie Sie diese erhalten, aber hier:

    a) Melden Sie sich an Ihrer Google-Entwicklerkonsole an: http://console.developers.google.com b) Erstellen Sie ein Projekt c) Erstellen Sie Ihre Anmeldeinformationen - verwenden Sie 'installierte Anwendung' d ) Fügen Sie die APIs hinzu, die Sie benötigen - ich denke, Drive API ist definitiv erforderlich. Ich habe auch Drive SDK für den Fall hinzugefügt.

  2. Kopieren Sie den folgenden Code in VS und bearbeiten Sie die erste Main () - Methode mit Ihrem Client-Schlüssel und Ihrem geheimen Schlüssel.

  3. Führen Sie die App aus und kopieren Sie das neue Zugriffstoken und das Aktualisierungstoken. Geben Sie diese und Ihre verbleibenden Anmeldeinformationen in die zweite Main () - Methode ein.

  4. Sie sollten jetzt in der Lage sein, die zweite Main () - Methode auszuführen (kehren Sie einfach die Benennung um). Ab jetzt ist das alles, was Sie brauchen - Sie müssen die erste Main () - Methode nicht erneut ausführen.

Übrigens wurde hier die erste Main () - Methode gefunden: https://developers.google.com/google-apps/spreadsheets/authorize

Ich habe jedoch den fehlenden Tokentyp sowie den Zugriffstyp hinzugefügt. Diese werden benötigt, verwenden Sie also den folgenden Code:

using System;
using Google.GData.Client;
using Google.GData.Spreadsheets;
using Google.GData.Documents;
using System.Configuration;
using System.Collections.Specialized;

namespace GoogleSpreadsheet
{
  class GoogleOAutho2
  {

    private static String folderName = "crazy.ivan";


    static void Main(string[] args)
    {
      ////////////////////////////////////////////////////////////////////////////
      // STEP 1: Configure how to perform OAuth 2.0
      ////////////////////////////////////////////////////////////////////////////

      // TODO: Update the following information with that obtained from
      // https://code.google.com/apis/console. After registering
      // your application, these will be provided for you.

      string CLIENT_ID = "your_client_id";

      // This is the OAuth 2.0 Client Secret retrieved
      // above.  Be sure to store this value securely.  Leaking this
      // value would enable others to act on behalf of your application!
      string CLIENT_SECRET = "your_secret_key"

      // Space separated list of scopes for which to request access.
      string SCOPE = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds https://docs.google.com/feeds";

      // This is the Redirect URI for installed applications.
      // If you are building a web application, you have to set your
      // Redirect URI at https://code.google.com/apis/console.
      string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";

      string TOKEN_TYPE = "refresh";

      ////////////////////////////////////////////////////////////////////////////
      // STEP 2: Set up the OAuth 2.0 object
      ////////////////////////////////////////////////////////////////////////////

      // OAuth2Parameters holds all the parameters related to OAuth 2.0.
      OAuth2Parameters parameters = new OAuth2Parameters();

      // Set your OAuth 2.0 Client Id (which you can register at
      // https://code.google.com/apis/console).
      parameters.ClientId = CLIENT_ID;

      // Set your OAuth 2.0 Client Secret, which can be obtained at
      // https://code.google.com/apis/console.
      parameters.ClientSecret = CLIENT_SECRET;

      // Set your Redirect URI, which can be registered at
      // https://code.google.com/apis/console.
      parameters.RedirectUri = REDIRECT_URI;

      ////////////////////////////////////////////////////////////////////////////
      // STEP 3: Get the Authorization URL
      ////////////////////////////////////////////////////////////////////////////

      // Set the scope for this particular service.
      parameters.Scope = SCOPE;

      parameters.AccessType = "offline"; // IMPORTANT and was missing in the original

      parameters.TokenType = TOKEN_TYPE; // IMPORTANT and was missing in the original


      // Get the authorization url.  The user of your application must visit
      // this url in order to authorize with Google.  If you are building a
      // browser-based application, you can redirect the user to the authorization
      // url.
      string authorizationUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
      Console.WriteLine(authorizationUrl);
      Console.WriteLine("Please visit the URL above to authorize your OAuth "
        + "request token.  Once that is complete, type in your access code to "
        + "continue...");
      parameters.AccessCode = Console.ReadLine();

      ////////////////////////////////////////////////////////////////////////////
      // STEP 4: Get the Access Token
      ////////////////////////////////////////////////////////////////////////////

      // Once the user authorizes with Google, the request token can be exchanged
      // for a long-lived access token.  If you are building a browser-based
      // application, you should parse the incoming request token from the url and
      // set it in OAuthParameters before calling GetAccessToken().
      OAuthUtil.GetAccessToken(parameters);
      string accessToken = parameters.AccessToken;
      string refreshToken = parameters.RefreshToken;
      Console.WriteLine("OAuth Access Token: " + accessToken + "\n");
      Console.WriteLine("OAuth Refresh Token: " + refreshToken + "\n");

      ////////////////////////////////////////////////////////////////////////////
      // STEP 5: Make an OAuth authorized request to Google
      ////////////////////////////////////////////////////////////////////////////

      // Initialize the variables needed to make the request
      GOAuth2RequestFactory requestFactory =
          new GOAuth2RequestFactory(null, "MySpreadsheetIntegration-v1", parameters);
      SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");
      service.RequestFactory = requestFactory;

      // Make the request to Google
      // See other portions of this guide for code to put here...

      // Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
      Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery();

      // Make a request to the API and get all spreadsheets.
      SpreadsheetFeed feed = service.Query(query);

      // Iterate through all of the spreadsheets returned
      foreach (SpreadsheetEntry entry in feed.Entries)
      {
        // Print the title of this spreadsheet to the screen
        Console.WriteLine(entry.Title.Text);
      }
      Console.ReadLine();

     }


    // once you copied your access and refresh tokens
    // then you can run this method directly from now on...
    static void MainX(string[] args)
    {
    GOAuth2RequestFactory requestFactory = RefreshAuthenticate();

         SpreadsheetsService service = new SpreadsheetsService("MySpreadsheetIntegration-v1");  
         service.RequestFactory = requestFactory;

      // Instantiate a SpreadsheetQuery object to retrieve spreadsheets.
      Google.GData.Spreadsheets.SpreadsheetQuery query = new Google.GData.Spreadsheets.SpreadsheetQuery();

      // Make a request to the API and get all spreadsheets.
      SpreadsheetFeed feed = service.Query(query);

      // Iterate through all of the spreadsheets returned
      foreach (SpreadsheetEntry entry in feed.Entries)
      {
        // Print the title of this spreadsheet to the screen
        Console.WriteLine(entry.Title.Text);
      }
      Console.ReadLine();



    public static GOAuth2RequestFactory RefreshAuthenticate() {
        OAuth2Parameters parameters = new OAuth2Parameters(){
            RefreshToken = "the_refresh_token_you_copied_from_the_CLI_running_the_first_method";
            AccessToken = "the_access_token_you_copied_from_the_CLI_running_the_first_method";
            ClientId = "your_client_id";
            ClientSecret = "your_dirty_little_secret";
            Scope = "https://www.googleapis.com/auth/drive https://spreadsheets.google.com/feeds",
            AccessType = "offline",
            TokenType = "refresh"
        };
        string authUrl = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
        return new GOAuth2RequestFactory(null, "evilspeculator", parameters);
    }
  }
}

Ich hoffe, das funktioniert für euch, viel Glück!

4
Molecool

Andrew Ich habe mich gefragt, wie Sie die google.apis.auth.oauth2-DLL erhalten haben. Ich versuche, Ihr Update zu implementieren, und ich kann den richtigen Weg zum Installieren der Bibliothek nicht finden. 

Ich habe das Gefühl, dass ich in der Lage sein werde, das zu erreichen, nachdem ich diesen Teil habe.

0
surewould