通过OAuth 2.0和私钥(即服务帐户)访问Google通讯录Api

Ra_*_*Ra_ 5 gdata-api google-api google-contacts-api oauth-2.0 service-accounts

我目前正在通过OAuth 2.0和所谓的服务帐户实施对Google通讯录的访问.为普通用户生成服务帐户,例如"My.Name@gmail.com".

生成OAuth 2.0凭据的代码是:

public static GoogleCredential getCredentials() throws GeneralSecurityException, IOException {
    GoogleCredential credential = new GoogleCredential.Builder().setTransport(HTTP_TRANSPORT)
            .setJsonFactory(JSON_FACTORY)
            .setServiceAccountId(SingleUserCredentials.SERVICE_ACCOUNT_EMAIL)
            .setServiceAccountScopes("https://www.google.com/m8/feeds")
            .setServiceAccountPrivateKeyFromP12File(new File(SingleUserCredentials.SERVICE_ACCOUNT_PKCS12_FILE_PATH))
            .build();
    credential.refreshToken();
    return credential;
}
Run Code Online (Sandbox Code Playgroud)

然后我试图通过以下方式检索联系人:

    ContactsService myService = new ContactsService(
            "myApp");

    myService.setOAuth2Credentials(getCredentials());

    URL feedUrl = new URL("https://www.google.com/m8/feeds/contacts/default/full");
    Query myQuery = new Query(feedUrl);
    ContactFeed resultFeed = myService.query(myQuery, ContactFeed.class);
    // Print the results

    for (ContactEntry entry : resultFeed.getEntries()) {
        System.out.println(entry.getName().getFullName().getValue());
        System.out.println("Updated on: " + entry.getUpdated().toStringRfc822());
    }
Run Code Online (Sandbox Code Playgroud)

问题是我的帐户中没有任何一个联系人.Feed始终为空.没有错误.没有.

通过相同的方法访问Google Apps托管域时,它可以正常运行.

我想知道在使用p12密钥文件和服务帐户时,Contacts Api是否支持普通(也称为@ gmail.com)帐户的OAuth 2.0.

小智 1

我自己也遇到了同样的问题。

我尝试了设置密钥时收到的电子邮件地址和域管理员的电子邮件地址。

当我使用密钥设置中的电子邮件时,我根本没有收到任何内容 - 没有警告,没有例外,也没有数据。

当我使用域管理员的电子邮件地址时,我收到一个异常:

com.google.api.client.auth.oauth2.TokenResponseException: 400 OK
     [java] {
     [java]   "error" : "invalid_grant"
     [java] }
     [java] Feb 5, 2013 5:16:48 PM com.google.appengine.repackaged.org.apache.http.impl.client.DefaultRequestDirector handleResponse
     [java] WARNING: Authentication error: Unable to respond to any of these challenges: {}
     [java] Feb 5, 2013 5:16:48 PM com.google.apphosting.utils.jetty.JettyLogger warn
     [java] WARNING: /
     [java] java.lang.NullPointerException: No authentication header information
Run Code Online (Sandbox Code Playgroud)

...

因此,我认为域管理员的电子邮件地址不是我需要的。

接下来,我在谷歌上搜索了一段时间才找到这个页面:

http://javadoc.google-api-java-client.googlecode.com/hg/1.13.2-beta/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.html

我在那里看到了getServiceAccountUser()。该字段的描述是:

返回应用程序尝试在服务帐户流中模拟的用户的电子邮件地址,如果没有或不使用服务帐户流,则返回 null。

果然,有一个相应的 setServiceAccountUser (String),它接受您使用服务帐户来模拟的用户的用户名(电子邮件地址)。

我将该字段设置为适当的值并且能够继续。

回想起来,这一切都是有道理的——如果我不提供我想要使用的帐户,我就无法删除该帐户的联系人。