Java Google联系人API访问服务帐户身份验证

Java Google联系人API访问服务帐户身份验证,java,google-api,authorization,google-oauth,google-api-java-client,Java,Google Api,Authorization,Google Oauth,Google Api Java Client,我正在尝试访问,但在获得授权后,我的尝试已失败。从其他(web)语言到APIConsole和公共API密钥(授权),我已经习惯了 GoogleCredential credential=new GoogleCredential().setAccessToken(“”); System.out.println(credential.refreshtToken());//假的 这样我就无法刷新令牌,也无法确定是否将公钥用作。。。相反,我尝试了一个: private静态最终字符串USER\u ACC

我正在尝试访问,但在获得授权后,我的尝试已失败。从其他(web)语言到APIConsole和公共API密钥(授权),我已经习惯了

GoogleCredential credential=new GoogleCredential().setAccessToken(“”);
System.out.println(credential.refreshtToken());//假的
这样我就无法刷新令牌,也无法确定是否将公钥用作。。。相反,我尝试了一个:

private静态最终字符串USER\u ACCOUNT\u EMAIL=”xy@gmail.com";
私有静态最终字符串服务\u帐户\u电子邮件=”xy@developer.gserviceaccount.com";
私有静态最终字符串服务\u帐户\u PKCS12\u文件\u PATH=“xy.p12”;
公共应用程序(){
Set scopes=new HashSet();
作用域。添加(“https://www.google.com/m8/feeds");
试一试{
GoogleCredential credential=新建GoogleCredential.Builder()
.setTransport(新的NetHttpTransport())
.setJsonFactory(新JacksonFactory())
.setServiceAccountId(服务\帐户\电子邮件)
.setServiceAccountScopes(范围)
.setServiceAccountUser(用户\帐户\电子邮件)
.setServiceAccountPrivateKeyFromp12文件(新的java.io.File(服务\帐户\ PKCS12\文件\路径))
.build();
System.out.println(credential.refreshtToken());
//System.out.println(credential.getAccessToken());
}捕获(一般安全性例外e){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
这是我的例外:

com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
        at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
        at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
        at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
        at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
        at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
        at App.<init>(App.java:50)
        at App.main(App.java:29)
com.google.api.client.auth.oauth2.TokenResponseException:401未经授权
位于com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
位于com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
位于com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
在com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
位于com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
应用程序(App.java:50)
位于App.main(App.java:29)

谢谢你的提示!

不用调用
setServiceAccountUser()
我的代码运行得很好。但是你只需要一个(服务帐户\u邮件)而不是你的个人联系人

“401 Unauthorized”异常的另一个可能来源是离开
credential.refreshtToken()

在完成的课程下面:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.gdata.client.contacts.ContactsService;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;

public class Connector {

  private static ContactsService contactService = null;
  private static HttpTransport httpTransport;

  private static final String APPLICATION_NAME = "Your-App/1.0";
  private static final String SERVICE_ACCOUNT_EMAIL = "xy@developer.gserviceaccount.com";

  private Connector() {
    // explicit private no-args constructor
  }

  public static ContactsService getInstance() {
    if (contactService == null) {
      try {
        contactService = connect();

      } catch (GeneralSecurityException | IOException e) {
        e.printStackTrace();
      }
    }

    return contactService;
  }

  private static ContactsService connect() throws GeneralSecurityException, IOException {
    httpTransport = GoogleNetHttpTransport.newTrustedTransport();

    // @formatter:off
    GoogleCredential credential = new GoogleCredential.Builder()
                                            .setTransport(httpTransport)
                                            .setJsonFactory(JacksonFactory.getDefaultInstance())
                                            .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                                            .setServiceAccountScopes(Collections.singleton("https://www.google.com/m8/feeds"))
                                            .setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
                                            .build();
    // @formatter:on

    if (!credential.refreshToken()) {
      throw new RuntimeException("Failed OAuth to refresh the token");
    }

    ContactsService myService = new ContactsService(APPLICATION_NAME);
    myService.setOAuth2Credentials(credential);
    return myService;
  }

}

你确定一个服务帐户有联系人吗?不是真的,但不是一个替代方案-它会在6天内关闭…我无法通过公共API访问该机制。有史以来最糟糕的解决方法:如果我向另一个API(如Google Plus)发出请求,第一个请求将返回一个有效的访问令牌。从那以后,我可以通过
setOAuth2Cr访问伊甸园()
到联系人API。不好玩:)将此作为答案发布。我喜欢黑客也许有一天会有用。背景:联系人API是一个古老的gdata API,非常基本,也很痛苦。Google plus是一个发现API,使用起来更容易。但是如果你想要个人帐户而不是服务帐户呢?嘿@StephanCelis试试这个作为一个u未测试的假设api如何处理个人帐户。将connect函数替换为:
private static contacts服务连接(字符串uname,字符串pw)抛出一般安全性异常,IOException{contactService=new contacts服务(应用程序名称);尝试{contactService.setUserCredentials(uname,pw)}catch(AuthenticationException异常){exception.printStackTrace();}返回myService;}
不要忘记启用。
com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized
        at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:105)
        at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
        at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
        at com.google.api.client.googleapis.auth.oauth2.GoogleCredential.executeRefreshToken(GoogleCredential.java:384)
        at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
        at App.<init>(App.java:50)
        at App.main(App.java:29)
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.gdata.client.contacts.ContactsService;

import java.io.File;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;

public class Connector {

  private static ContactsService contactService = null;
  private static HttpTransport httpTransport;

  private static final String APPLICATION_NAME = "Your-App/1.0";
  private static final String SERVICE_ACCOUNT_EMAIL = "xy@developer.gserviceaccount.com";

  private Connector() {
    // explicit private no-args constructor
  }

  public static ContactsService getInstance() {
    if (contactService == null) {
      try {
        contactService = connect();

      } catch (GeneralSecurityException | IOException e) {
        e.printStackTrace();
      }
    }

    return contactService;
  }

  private static ContactsService connect() throws GeneralSecurityException, IOException {
    httpTransport = GoogleNetHttpTransport.newTrustedTransport();

    // @formatter:off
    GoogleCredential credential = new GoogleCredential.Builder()
                                            .setTransport(httpTransport)
                                            .setJsonFactory(JacksonFactory.getDefaultInstance())
                                            .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                                            .setServiceAccountScopes(Collections.singleton("https://www.google.com/m8/feeds"))
                                            .setServiceAccountPrivateKeyFromP12File(new File("key.p12"))
                                            .build();
    // @formatter:on

    if (!credential.refreshToken()) {
      throw new RuntimeException("Failed OAuth to refresh the token");
    }

    ContactsService myService = new ContactsService(APPLICATION_NAME);
    myService.setOAuth2Credentials(credential);
    return myService;
  }

}