Java TokenResponseException:401尝试访问Google Contacts Api时未经授权

Java TokenResponseException:401尝试访问Google Contacts Api时未经授权,java,oauth-2.0,google-contacts-api,Java,Oauth 2.0,Google Contacts Api,我试图连接到google Contacts api以访问保存在google中的我的联系人/联系人,但它抛出了一个令牌响应异常:401 Unauthorized。我对谷歌Oauth2.0有些陌生。我已根据需要将服务帐户密钥文件下载到我的项目根目录中 代码如下: import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.javanet.Go

我试图连接到google Contacts api以访问保存在google中的我的联系人/联系人,但它抛出了一个令牌响应异常:401 Unauthorized。我对谷歌Oauth2.0有些陌生。我已根据需要将服务帐户密钥文件下载到我的项目根目录中

代码如下:

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.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;

public class Connector {
private static ContactsService contactService = null;
    private static HttpTransport httpTransport;

    private static final String APPLICATION_NAME = "example";
    private static final String SERVICE_ACCOUNT_EMAIL = "example_mail@example-166608.iam.gserviceaccount.com";
    private static final java.util.List<String> SCOPE = Arrays.asList("https://www.google.com/m8/feeds/");

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

    public static void main(String[] args) {
        System.out.println(getInstance());
    }

    public static ContactsService getInstance() {
        if (contactService == null) {
            try {
                contactService = connect();
            } catch (GeneralSecurityException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return contactService;
    }

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

        java.io.File p12File = new java.io.File("example-e8135faedf4e.p12");

        // @formatter:off
        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(httpTransport)
                .setJsonFactory(JacksonFactory.getDefaultInstance())
                .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
                .setServiceAccountScopes(SCOPE)
                .setServiceAccountPrivateKeyFromP12File(p12File)
                .setServiceAccountUser("example@gmail.com")
                .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;
    }
}
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
导入com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
导入com.google.api.client.http.HttpTransport;
导入com.google.api.client.json.jackson2.JacksonFactory;
导入com.google.gdata.client.contacts.contacts服务;
导入java.io.IOException;
导入java.security.GeneralSecurityException;
导入java.util.array;
公共类连接器{
专用静态联系人服务联系人服务=null;
专用静态HttpTransport-HttpTransport;
私有静态最终字符串应用程序\u NAME=“示例”;
私有静态最终字符串服务\u帐户\u电子邮件=“示例_mail@example-166608.iam.gserviceaccount.com”;
private static final java.util.List SCOPE=Arrays.asList(“https://www.google.com/m8/feeds/");
专用连接器(){
//显式私有无参数构造函数
}
公共静态void main(字符串[]args){
System.out.println(getInstance());
}
公共静态联系人服务getInstance(){
if(contactService==null){
试一试{
contactService=connect();
}捕获(一般安全性例外e){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
}
退货服务;
}
私有静态联系人服务连接()引发GeneralSecurityException,IOException{
httpTransport=GoogleNetHttpTransport.newTrustedTransport();
java.io.File p12File=new java.io.File(“example-e8135faedf4e.p12”);
//@formatter:off
GoogleCredential credential=新建GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JacksonFactory.getDefaultInstance())
.setServiceAccountId(服务\帐户\电子邮件)
.setServiceAccountScopes(范围)
.SetServiceAccountPrivateKeyfromP12文件(P12文件)
.setServiceAccountUser(“example@gmail.com")
.build();
//@formatter:on
如果(!credential.refreshToken()){
抛出新的RuntimeException(“OAuth刷新令牌失败”);
}
ContactsService myService=新的ContactsService(应用程序名称);
myService.setOAuth2Credentials(凭证);
返回myService;
}
}
但是,会引发以下异常:

com.google.api.client.auth.oauth2.TokenResponseException:401未经授权的
null
位于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) at Connector.connect(Connector.java:58)at Connector.getInstance(Connector.java:31)位于 Connector.main(Connector.java:25)构建成功(总时间:9 秒)

基于此,
TokenResponseException
可能是由无效的客户机ID、客户机机密或作用域以及刷新令牌过度使用等多种原因造成的。还指出,“401 Unauthorized”异常的另一个可能来源是离开
credential.refreshtToken()
。调用是将访问代码写入引用所必需的


其他参考资料也可能有所帮助:

我发现您的代码与Quickstart示例中的代码非常相似。如果这至少奏效了一次,请检查您是否在tokens文件夹下保存了任何token。

我很晚才看到这种情况,但感谢您的帮助。我能够解决这个问题,让我发布最终的代码shortly@MichaelGatumaSelvatico:你的解决方案是什么。@Michaelgatumaselvatio也为他的最后一个定理找到了一个简单的证明,但他没有写出来。这导致数十名数学家在未来的三个世纪里陷入疯狂。