2014-07-16 15 views
8

Ho un'applicazione desktop per leggere la posta utilizzando l'API GMAIL sull'interfaccia REST. Voglio utilizzare l'account di servizio in modo che possiamo scaricare i messaggi utilizzando le impostazioni del dominio e l'interazione dell'utente è nullo. Sono successo in grado di creare l'istanza di Gmail di servizio, ma quando provo ad accedere a qualsiasi metodo API Gmail come andare a prendere i messaggi della lista o di qualsiasi altra ottengo un'eccezione dicendoPossiamo accedere all'API GMAIL utilizzando l'account di servizio?

Google.Apis.Auth.OAuth2.Responses.TokenResponseException: Error:"access_denied", Description:"Requested client not authorized."

mi sono fatto con tutte le impostazioni al Console per gli sviluppatori e ha aggiunto ambiti al mio dominio gapps.

L'account di servizio dell'API di Gmail è supportato? Utilizzando la stessa impostazione e l'account di servizio, sono in grado di ottenere l'elenco di tutti i file nell'unità Google utilizzando il servizio Drive e l'API.

risposta

12

Io uso il seguente codice C# per l'accesso a Gmail da un account di servizio

String serviceAccountEmail = 
    "[email protected]ount.com"; 

var certificate = new X509Certificate2(
    AppDomain.CurrentDomain.BaseDirectory + 
     "certs//fe433c710f4980a8cc3dda83e54cf7c3bb242a46-privatekey.p12", 
    "notasecret", 
    X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable); 

string userEmail = "[email protected]"; 

ServiceAccountCredential credential = new ServiceAccountCredential(
    new ServiceAccountCredential.Initializer(serviceAccountEmail) 
    { 
     User = userEmail, 
     Scopes = new[] { "https://mail.google.com/" } 
    }.FromCertificate(certificate) 
); 

if (credential.RequestAccessTokenAsync(CancellationToken.None).Result) 
{ 
    GmailService gs = new GmailService(
     new Google.Apis.Services.BaseClientService.Initializer() 
     { 
      ApplicationName = "iLink", 
      HttpClientInitializer = credential 
     } 
    ); 

    UsersResource.MessagesResource.GetRequest gr = 
     gs.Users.Messages.Get(userEmail, msgId); 
    gr.Format = UsersResource.MessagesResource.GetRequest.FormatEnum.Raw; 
    Message m = gr.Execute(); 

    if (gr.Format == UsersResource.MessagesResource.GetRequest.FormatEnum.Raw) 
    { 
     byte[] decodedByte = FromBase64ForUrlString(m.Raw); 
     string base64Encoded = Convert.ToString(decodedByte); 
     MailMessage msg = new MailMessage(); 
     msg.LoadMessage(decodedByte); 
    } 
} 
+0

anche io sto seguendo lo stesso processo ma ottenendo l'eccezione, potresti dirmi quale elenco di tutti gli ambiti devo aggiungere al mio livello di dominio Google Apps? –

+0

Sto usando un'app di mercato. Ho https://www.googleapis.com/auth/userinfo.email \t https://www.googleapis.com/auth/userinfo.profile \t https://mail.google.com/ – PNC

+0

Sei stato in grado di inviare mail usando questo codice? –

2

Sì, è possibile ... controllare le impostazioni di delega ...

https://developers.google.com/admin-sdk/directory/v1/guides/delegation#delegate_domain-wide_authority_to_your_service_account

Edit: Utilizzare il collegamento Eric DeFriez condiviso.

+0

ancora sto ottenendo l'eccezione di cui sopra. Di seguito sono elencati il ​​mio elenco di obiettivi :: Provisioning utente (sola lettura) https://apps-apis.google.com/a/feeds/user/#readonly https://docs.google.com/feeds Email (leggi/Scrivi/Invia) https://mail.google.com/ https://www.googleapis.com/auth/admin.directory.group https://www.googleapis.com/auth/admin.directory.user https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/gmail.comoggetto https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.readonly Devo aggiungere più elenchi di obiettivi? –

+0

sto utilizzando un account di prova e non ottengo questa opzione, solo dice 'Gestisci accesso client OAuth'. è a causa della prova o c'è qualche configurazione richiesta –

3

Se si desidera "leggere la posta", è necessaria la nuova API di Gmail (non l'API delle impostazioni dell'amministratore più vecchie a cui è stato fatto notare "perso in binario"). Sì, è possibile farlo con OAuth2 e il più recente di Gmail API, è necessario whitelist lo sviluppatore in cPanel e creare una chiave è possibile firmare le vostre richieste con - ci vuole un po 'per l'installazione: https://developers.google.com/accounts/docs/OAuth2ServiceAccount#formingclaimset

+0

Interessante! Sto capendo correttamente che con questo metodo si dovrebbe essere in grado di utilizzare un account di servizio per accedere ai nuovi metodi dell'API di Gmail su tutti gli utenti del dominio di Google Apps? La risposta contiene informazioni su utenti specifici a cui sono destinati i risultati restituiti? Accedendo all'API di Gmail utilizzando Oauth tradizionale, il contesto di un utente è implicito, pertanto la risposta non deve contenere informazioni utente contestuali come ID utente, ecc. –

+1

Più una domanda oauth2 a questo punto, quindi spero che uno degli esperti di autenticazione possa commentare, tuttavia la mia comprensione è come parte di ogni richiesta che si genera l'ID utente (indirizzo email) a cui si desidera accedere con tale richiesta. Utilizzerai la tua chiave privata, ecc. Per creare questo. Quindi sarai autorizzato una sola volta per l'intero dominio (in Cpanel) ma puoi richiedere l'accesso per qualsiasi utente nel dominio e ovviamente saprai chi è in anticipo. –

+1

Funziona con un normale account Gmail? O deve essere un account di dominio? – Rahatur

0

È possibile accedere a qualsiasi [email protected]_DOMAIN.COM mails/etichette/le discussioni ecc con il nuovo Gmail API:

https://developers.google.com/gmail/api/

tramite account di servizio con impersonificazione (l'account di servizio accede a api come se fosse un utente specifico del proprio dominio).

vedere i particolari qui: https://developers.google.com/identity/protocols/OAuth2ServiceAccount

Ecco relativo codice in Dartlang:

import 'package:googleapis_auth/auth_io.dart' as auth; 
import 'package:googleapis/gmail/v1.dart' as gmail; 
import 'package:http/http.dart' as http; 

///credentials created with service_account here https://console.developers.google.com/apis/credentials/?project=YOUR_PROJECT_ID 
final String creds = r''' 
{ 
    "private_key_id": "FILL_private_key_id", 
    "private_key": "FILL_private_key", 
    "client_email": "FILL_service_account_email", 
    "client_id": "FILL_client_id", 
    "type": "service_account" 
}'''; 


Future<http.Client> createImpersonatedClient(String impersonatedUserEmail, List scopes) async { 
    var impersonatedCredentials = new auth.ServiceAccountCredentials.fromJson(creds,impersonatedUser: impersonatedUserEmail); 
    return auth.clientViaServiceAccount(impersonatedCredentials , scopes); 
} 



getUserEmails(String userEmail) async { //userEmail from YOUR_DOMAIN.COM 
    var client = await createImpersonatedClient(userEmail, [gmail.GmailApi.MailGoogleComScope]); 
    var gmailApi = new gmail.GmailApi(client); 
    return gmailApi.users.messages.list(userEmail, maxResults: 5); 
} 
Problemi correlati