12

Mi sto picchiando maledettamente cercando di ottenere un semplice accesso all'accesso del servizio per lavorare in C#, a Google API e Google Analytics. La mia azienda sta già acquisendo dati in Analytics e posso interrogare le informazioni con il loro Query Explorer, ma iniziare a .Net non sta andando da nessuna parte. Sto utilizzando un file JSON generato da Google con PKI, in quanto la documentazione dice che tale account di servizio è il modo corretto per le comunicazioni da computer a computer con API Googla. Pezzo di codice presentato:Come accedere all'API di Google con account di servizio in C# - Credenziali non valide

public static GoogleCredential _cred; 
public static string _exePath; 

static void Main(string[] args) { 
    _exePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase).Replace(@"file:\", ""); 
    var t = Task.Run(() => Run()); 
    t.Wait(); 
} 

private static async Task Run() { 
    try { 
     // Get active credential 
     using (var stream = new FileStream(_exePath + "\\Default-GASvcAcct-508d097b0bff.json", FileMode.Open, FileAccess.Read)) { 
      _cred = GoogleCredential.FromStream(stream); 
     } 
     if (_cred.IsCreateScopedRequired) { 
     _cred.CreateScoped(new string[] { AnalyticsService.Scope.Analytics }); 
     } 
     // Create the service 
     AnalyticsService service = new AnalyticsService(
      new BaseClientService.Initializer() { 
       HttpClientInitializer = _cred, 
      }); 
     var act1 = service.Management.Accounts.List().Execute(); // blows-up here 

Tutto compila bene, ma quando ha colpito l'istruzione Execute(), viene generato un errore di GoogleApiException:

[credenziali non valide] Località [Autorizzazione - intestazione] Motivo [authError ] dominio [global]

che cosa mi manca?

risposta

17

Sembra che il GoogleAnalytics non può consumare un generico GoogleCredential e lo interpretano come un ServiceAccountCredential (anche se è riconosciuto, interally, che è in realtà di quel tipo). Quindi devi creare un ServiceAccountCredential nel modo più difficile. È anche un peccato che lo GoogleCredential non esponga le varie proprietà della credenziale, quindi ho dovuto costruirne una mia.
Ho utilizzato il generatore di classe JSON C# a http://jsonclassgenerator.codeplex.com/ per creare un oggetto "personale" ServiceAccountCredential utilizzando la libreria JSON che è una parte automatica dell'API di Google (Newtonsoft.Json), recuperato le parti essenziali del file json scaricato dell'account di servizio , per costruire la credenziale richiesta, usando le sue proprietà di email e chiave privata. Passare un'autentica ServiceAccountCredential al costruttore del servizio GoogleAnalytics, comporta un accesso corretto e l'accesso alle risorse consentite dell'account.

Esempio di codice funzionante sotto:

using System; 
using System.Diagnostics; 
using System.IO; 
using System.Reflection; 
using System.Text; 
using Google.Apis.Auth.OAuth2; 
using Google.Apis.Services; 
using Google.Apis.Analytics.v3; 
using Newtonsoft.Json; 
    . 
    . 
    . 
try 
{ 
    // Get active credential 
    string credPath = _exePath + @"\Private-67917519b23f.json"; 

    var json = File.ReadAllText(credPath); 
    var cr = JsonConvert.DeserializeObject<PersonalServiceAccountCred>(json); // "personal" service account credential 

    // Create an explicit ServiceAccountCredential credential 
    var xCred = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(cr.ClientEmail) 
    { 
     Scopes = new[] { 
      AnalyticsService.Scope.AnalyticsManageUsersReadonly, 
      AnalyticsService.Scope.AnalyticsReadonly 
     } 
    }.FromPrivateKey(cr.PrivateKey)); 

    // Create the service 
    AnalyticsService service = new AnalyticsService(
     new BaseClientService.Initializer() 
     { 
      HttpClientInitializer = xCred, 
     } 
    ); 

    // some calls to Google API 
    var act1 = service.Management.Accounts.List().Execute(); 

    var actSum = service.Management.AccountSummaries.List().Execute(); 

    var resp1 = service.Management.Profiles.List(actSum.Items[0].Id, actSum.Items[0].WebProperties[0].Id).Execute(); 

Alcuni potrebbero chiedersi che cosa un account di servizio credenziale generato da Google con PKI (chiave privata) assomiglia. Da Google APIs Manager (IAM & Admin) al numero https://console.developers.google.com/iam-admin/projects, seleziona il progetto appropriato (ne hai almeno uno). Ora selezionare Account di servizio (dai collegamenti di navigazione sinistro) e CREARE ACCOUNT SERVIZIO nella parte superiore dello schermo. Inserire un nome, impostare la casella Fornire una nuova chiave privata, quindi fare clic su Creare. Google causerà un download automatico di un file JSON, simile a questo:

{ 
    "type": "service_account", 
    "project_id": "atomic-acrobat-135", 
    "private_key_id": "508d097b0bff9e90b8d545f984888b0ef31", 
    "private_key": "-----BEGIN PRIVATE KEY-----\nMIIE...o/0=\n-----END PRIVATE KEY-----\n", 
    "client_email": "[email protected]", 
    "client_id": "1123573016559832", 
    "auth_uri": "https://accounts.google.com/o/oauth2/auth", 
    "token_uri": "https://accounts.google.com/o/oauth2/token", 
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/google-analytics%40atomic-acrobat-135923.iam.gserviceaccount.com" 
} 
+0

Sembra che qualcuno abbia usato il tuo codice e lo abbia usato sul suo blog. perchè hai risposto a questo nel 2016 e il suo blog è recente. La mia domanda è posso ottenere un token di accesso usando questo..so posso usare il token di accesso per l'API embed. perchè sto ricevendo un token di accesso nullo. – CyberNinja

+0

Ero troppo pigro per usare il tuo generatore di classi. Così invece ho fatto questo: 'Newtonsoft.Json.Linq.JObject cr = (Newtonsoft.Json.Linq.JObject) JsonConvert.DeserializeObject (json); string s = (string) cr.GetValue ("private_key"); 'Grazie per la tua risposta-- ha aiutato molto. – robertpb

Problemi correlati