Java Google 联系人 API 访问服务帐户身份验证
Java Google Contacts API Access Service Account Authentication
我正在尝试访问 Googles Contacts API,但我的尝试在获得授权时已经失败。对于其他(网络)语言,我习惯了 API 控制台和 public API 键(授权)。
GoogleCredential credential = new GoogleCredential().setAccessToken("<<PublicAPIKey>>");
System.out.println(credential.refreshToken()); // false
这样我就无法刷新令牌并且不确定是否将 public-key 用作 accesstoken... Instead I tried over a service account:
private static final String USER_ACCOUNT_EMAIL = "xy@gmail.com";
private static final String SERVICE_ACCOUNT_EMAIL = "xy@developer.gserviceaccount.com";
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "xy.p12";
public App() {
Set<String> scopes = new HashSet<String>();
scopes.add("https://www.google.com/m8/feeds");
try {
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(new NetHttpTransport())
.setJsonFactory(new JacksonFactory())
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(scopes)
.setServiceAccountUser(USER_ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
System.out.println(credential.refreshToken());
//System.out.println(credential.getAccessToken());
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
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)
感谢提示!
没有调用 setServiceAccountUser()
,我的代码运行得非常好。但是您只会有一个 impersonated account (service_account_mail) 而不是您的个人联系人。
“401 未经授权”异常的另一个可能来源是离开 credential.refreshToken()
。该调用是将访问代码写入参考所必需的。
下面完成class:
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;
}
}
我正在尝试访问 Googles Contacts API,但我的尝试在获得授权时已经失败。对于其他(网络)语言,我习惯了 API 控制台和 public API 键(授权)。
GoogleCredential credential = new GoogleCredential().setAccessToken("<<PublicAPIKey>>");
System.out.println(credential.refreshToken()); // false
这样我就无法刷新令牌并且不确定是否将 public-key 用作 accesstoken... Instead I tried over a service account:
private static final String USER_ACCOUNT_EMAIL = "xy@gmail.com";
private static final String SERVICE_ACCOUNT_EMAIL = "xy@developer.gserviceaccount.com";
private static final String SERVICE_ACCOUNT_PKCS12_FILE_PATH = "xy.p12";
public App() {
Set<String> scopes = new HashSet<String>();
scopes.add("https://www.google.com/m8/feeds");
try {
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(new NetHttpTransport())
.setJsonFactory(new JacksonFactory())
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(scopes)
.setServiceAccountUser(USER_ACCOUNT_EMAIL)
.setServiceAccountPrivateKeyFromP12File(new java.io.File(SERVICE_ACCOUNT_PKCS12_FILE_PATH))
.build();
System.out.println(credential.refreshToken());
//System.out.println(credential.getAccessToken());
} catch (GeneralSecurityException e) {
e.printStackTrace();
} catch (IOException e) {
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)
感谢提示!
没有调用 setServiceAccountUser()
,我的代码运行得非常好。但是您只会有一个 impersonated account (service_account_mail) 而不是您的个人联系人。
“401 未经授权”异常的另一个可能来源是离开 credential.refreshToken()
。该调用是将访问代码写入参考所必需的。
下面完成class:
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;
}
}