我正在用Java编写一个后端进程,它将模拟一个用户,并在他们的Google Drive上添加/删除文档。
服务器帐户似乎正确地进行了身份验证,但当我尝试冒充用户时,我会收到一个401未授权错误
。有关详细信息,请参阅下面。
配置
我已按如下方式配置了服务器帐户:
我已使用管理API客户端访问屏幕配置域,以授权110XXXXXXXX342具有以下范围:https://www.googleapis.com/auth/drive.
谷歌支持看了我的配置,并给了它竖起大拇指。
然后我的代码如下所示:
package com.dcm.sharingdocuments;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Map.Entry;
import com.google.api.client.auth.oauth2.TokenErrorResponse;
import com.google.api.client.auth.oauth2.TokenResponseException;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.FileList;
public class SharingDocumentsTest3 {
private static final String SERVICE_ACCOUNT_EMAIL = " anothertest@yyyyyyyyy.iam.gserviceaccount.com";
public static Drive getDriveService(String userEmail) throws Exception {
File keyFile = new File("E:\\Projects\\Workspace\\Sharing Documents\\authentication\\AnotherTestKeyFile.p12");
HttpTransport httpTransport = new NetHttpTransport();
JacksonFactory jsonFactory = new JacksonFactory();
List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE_METADATA_READONLY);
GoogleCredential credential = null;
if (userEmail == null) {
credential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL).setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKeyFromP12File(keyFile).build();
credential.refreshToken();
} else {
credential = new GoogleCredential.Builder().setTransport(httpTransport).setJsonFactory(jsonFactory)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL).setServiceAccountScopes(SCOPES)
.setServiceAccountPrivateKeyFromP12File(keyFile).setServiceAccountUser(userEmail).build();
credential.refreshToken();
}
Drive service = new Drive.Builder(httpTransport, jsonFactory, null).setHttpRequestInitializer(credential)
.build();
return service;
}
public static void main(String[] args) {
SharingDocumentsTest3 sdt3 = new SharingDocumentsTest3();
sdt3.execute();
}
private void execute() {
try {
Drive service = getDriveService(null);
Drive services = getDriveService("anzzzze@zzzzz.me.uk");
displayFiles(services);
} catch (Exception e) {
e.printStackTrace();
}
}
private void displayFiles(Drive service) throws Exception {
FileList result = service.files().list().setPageSize(10).execute();
List<com.google.api.services.drive.model.File> files = result.getFiles();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (com.google.api.services.drive.model.File file : files) {
Set<Entry<String, Object>> entries = file.entrySet();
Iterator<Entry<String, Object>> it = entries.iterator();
while (it.hasNext()) {
Entry<String, Object> entry = it.next();
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String) {
System.out.println("\tKey = " + key + ", Value = " + (String) value);
} else {
System.out.println("\tKey = " + key + ", Value = " + value.toString());
}
}
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
}
}
当我像上面那样运行代码时,我得到了错误:
Mar 29, 2017 9:55:27 AM com.google.api.client.googleapis.services.AbstractGoogleClient <init>
WARNING: Application name is not set. Call Builder#setApplicationName.
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 com.dcm.sharingdocuments.SharingDocumentsTest3.getDriveService(SharingDocumentsTest3.java:50)
at com.dcm.sharingdocuments.SharingDocumentsTest3.execute(SharingDocumentsTest3.java:75)
at com.dcm.sharingdocuments.SharingDocumentsTest3.main(SharingDocumentsTest3.java:65)
因此,当我设置setServiceAccount tUser时,代码在credential.refreshToken()失败。当我不这样做时,它似乎已经成功刷新了令牌。我尝试了此代码的各种组合——例如注释掉刷新令牌()行,注释掉getDriveService(null)行——但是每当我尝试使用/刷新为模拟用户获得的凭据时,我都会收到401未授权错误。
如果我修改代码以便将getDriveService(null)获得的驱动器传递给DisplayFiles(...),然后我会列出一个名为“入门”的文件。因此,看起来服务帐户授权正在工作,Google已经将他们的默认文件添加到服务器帐户的驱动器中。
我使用< code>google-*1.22.0.jar文件和< code>Java 1.8来运行上述代码
我认为问题在于我配置域的方式,或者我试图模拟用户的方式,但我的代码看起来像web上的许多示例,Google支持似乎表明我正确配置了域。
任何您可以建议的解决方案或下一步将不胜感激!
我在这个问题上纠结了很久,终于找到了自己的问题。“管理API客户端访问”管理控制台中肯定有一个错误...
您必须将“客户ID”(例如110XXXXXXXX342)作为客户名称,而不是“服务帐户ID”(看起来像电子邮件)。现在,他们的文档是正确的,他们在文档中说要使用客户ID,我必须给他们。
这就是错误。当我到达ManageAPI屏幕时,我看到了“Example:www.Example.com”。我在那里输入了服务帐户ID,认为电子邮件地址格式与“www.example.com”的匹配比客户ID更好。我按下了“授权”,条目显然已被接受,一切都很好。结果如下:
它甚至从服务ID生成了客户端ID!太好了!除了每次我尝试与setServiceUser()
连接时,我的代码都会出现401错误。
如果我返回到管理API客户端访问控制台,如果我删除前面的条目并执行相同的操作,只是使用客户端ID而不是服务ID。结果是这样的:
完全一样,但现在我没有得到401错误。因此,没有办法查看控制台,知道您是否成功配置了它。我测试了三次,以确保我没有失去理智。。。
之后,我得到以下错误: 我们使用的是restapi.php (a)我们使用的是G套件“基本版”;那有什么限制吗?(b)我们从PHP(7.0)环境中调用G-Suite API;是否有任何已知的问题,因为环境仍然标记为'(Beta)'。(c)是否有任何样例/教程可以给出解决我们问题的指针。
我想在Visual Studio 2008中将one drive for business集成到我的windows窗体应用程序中。我已经按照链接“https://dev . one drive . com/auth/aad _ oauth . htm”进行了Azure注册和Office 365认证。我可以获得登录用户的“https://{ tenant }-my . SharePoint . co
我正在尝试在twitter上创建一个应用程序。当我登录时,它会给我以下错误- 错误-是否授权“”使用您的帐户? 我得到以下错误在访问请求令牌(https://api.twitter.com/oauth/request_token)- 错误-无法验证oauth签名和令牌。 我正在做的是重定向用户到: https://twitter.com/oauth/authenticate?oauth_token
我在公司Gmail账户,特别是Gsuite Gmail账户中阅读邮件时遇到了问题。 我已经遵循了以下步骤: 转到Google API控制台。 创建一个新项目。 创建一个新的服务帐户 获取p12格式的私钥 允许谷歌办公套件向服务帐户授权。 转到GSuite管理面板。 去保安科 允许电子邮件范围(读/写/发送)https://mail.google.com/到服务帐户。 我做了如下代码:(https:
我有一个具有域范围委托设置的服务帐户,我正在尝试使用该服务帐户创建新帐户(google api服务管理目录),然后向新创建的帐户添加一些预设日历(google api services日历)。 我在目录api方面没有任何问题。我必须使用服务帐户创建一个委派(管理)用户,所有目录api调用都工作正常。 然而,我在日历api调用工作时遇到了问题。 Java依赖性: Java代码: 堆栈跟踪 : 有趣的
我们正在尝试创建一个与谷歌管理SDK的集成,以便能够检索,更新和创建帐户在我们的领域。但是,我们不断收到一个403错误,表明我们没有被授权访问Resource/API。 我们正在使用从一个服务帐户获得的凭据,该帐户启用了域范围的授权,并且具有以下两个作用域:https://www.googleapis.com/auth/admin.directory.user.readonly,https://w