- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在用 Java 编写一个后端进程,它将模拟用户并在他们的 Google 云端硬盘上添加/删除文档。
服务器帐户似乎正确地进行了身份验证,但是当我尝试模拟用户时,我收到了 401 Unauthorized 错误
。详情请见下文。
配置
我已经配置服务器帐户如下:
我已使用管理 API 客户端访问屏幕配置域以授权 110xxxxxxxxx342 具有范围:https://www.googleapis.com/auth/drive .
Google 支持人员查看了我的配置并对它竖起了大拇指。
我的代码如下所示:
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)
因此,当我设置 setServiceAccountUser 时,代码在 credential.refreshToken() 处失败。当我没有时,它似乎已经成功刷新了 token 。我尝试了这段代码的各种组合——例如注释掉了 refreshToken() 行,注释掉了 getDriveService(null) 行——但是每当我尝试使用/刷新为模拟用户获得的凭据时,我都会收到 401 Unauthorized 错误。
如果我修改代码以便将 getDriveService(null) 获得的驱动器传递给 DisplayFiles(...),那么我会得到一个名为“Getting Started”的文件。因此,服务帐户授权似乎有效,Google 已将其默认文件添加到服务器帐户的驱动器中。
我正在使用 google-*1.22.0.jar
文件和 Java 1.8
来运行上面的代码
我认为问题在于我配置域的方式或我尝试模拟用户的方式,但我的代码看起来与网络上的许多示例一样,Google 支持似乎说我已正确配置域.
如果您有任何建议作为解决方案或下一步,我们将不胜感激!
最佳答案
在这个问题上卡了很久,终于找到问题所在了。 “管理 API 客户端访问”管理控制台中肯定存在错误...
您必须将“客户端 ID”(例如 110xxxxxxxxx342)作为客户端名称,而不是“服务帐户 ID”(看起来像电子邮件的那个)。现在,their documentation is correct ,他们确实在文档中说要使用客户端 ID,我必须给他们。
所以这是错误。当我到达“管理 API”屏幕时,我看到“示例:www.example.com”。我在那里输入了服务帐户 ID,认为电子邮件地址格式比客户端 ID 更匹配“www.example.com”。我按下“授权”,条目显然已被接受,一切都很好。结果如下所示:
它甚至可以从服务 ID 生成客户端 ID!伟大的!除了每次尝试连接 setServiceUser()
时我的代码都会出现 401 错误。
如果我返回管理 API 客户端访问控制台并删除之前的条目并执行相同的操作,但使用客户端 ID 而不是服务 ID。结果是这样的:
完全一样,但现在我没有收到 401 错误。 所以没有办法查看控制台,并知道您是否已成功配置它。我测试了 3 次以确保我没有失去理智... p>
关于java - 使用服务器帐户模拟用户以访问其 Google Drive 时出现 401 Unauthorized 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43090022/
尝试使用以下命令将我的Docker容器推送到Bluemix: sudo docker push registry.ng.bluemix.net//testproj:latest ...但是它保持这种状
我正在运行最新的 Raspbian 发行版并且刚刚安装了 transmission包。 但是,每当我运行 transmission-remote命令 - 例如,要更改一些基本配置 - 我不断收到相同的
我已经使用 Ruby Gem rest-client 来请求网站的 url。我收到以下错误... RestClient::Unauthorized (401 Unauthorized): app/
安装 kube-dns 插件时出现问题。 我的操作系统是 CentOS Linux release 7.0.1406 (Core) Kernel:Linux master 3.10.0-693.el7
我在 ubunto 16 上安装了 Coturn 服务器 目前我正在检查它 function checkTURNServer(turnConfig, timeout){ return new Pr
我正在尝试使用Azure上部署的Kubernetes 1.9.9在新设置的AKS群集上使用Kubernetes仪表板。 我运行kubectl proxy并打开http://localhost:8001
我想测试来自java的Rest接口(interface)。目的是检查 jpg 图像中是否找到任何人脸。我为此使用的 res 调用是 ../face/v1.0/detect 我将 Ocp-Apim-Su
所以我有自己的解析服务器,运行着heroku。 此云代码功能: Parse.Cloud.define("ReadyUp", function(request, response) {
今天,我开始收到此错误,据我所知,没有任何原因。这不是一个一致的错误。今天突然开始了。它昨天运行完美,并且几个星期都没有任何错误。 文件中只有 file_get_contents()。 一段时间以来,
我试图让用户在 Laravel 8 中查看类别页面 CategoryPolicy.php use App\Models\Category; use App\Models\User; use Illum
我正在尝试从 Nexus 存储库中查看我的代码。 首先,我已经生成了密码 mvn --encrypt-master-password _mypassword_ 这是我的 c:/Users/joanet
我使用的是最新的开源 formsflow.ai v4.0.2。我将整个项目带到了我的个人笔记本电脑上。我遵循了 Docker 完整安装指南。 Docker 运行良好。在 http://localhos
我已根据 ADLS Gen2 容器中存储的 parquet 文件在 Azure Synapse 中创建了一个外部表。我使用以下三个查询来创建数据源、文件格式和表: CREATE EXTERNAL DA
我正在尝试按照示例项目和来自 here 的教程将示例 Power BI 仪表板嵌入到 WPF 应用程序中.当我启动该应用程序时,我必须输入我的密码来验证我自己,当它尝试使用 getAppWorkspa
因此,我正在尝试使用kubernetes(minikube)。我是一个初学者,对docker有一些基本的经验。 事实证明,我2天前安装了kubernetes,却没有做任何事情。 我几乎没有设法连接到仪
所以问题是:我最近做了 this post . 我提到的解决方案适用于一个 token 和一个 API,但当我尝试使用两个 token (gmail 和 Sheets API)处理两个 API 时,它
我正在使用 Java 开发一个包含文本转语音功能的应用程序。我使用了 IBM Watson Text-to Speech API,但我的代码总是出现未经授权的错误。有人能帮我修复它吗?非常感谢! Ia
我正在尝试按照示例项目和来自 here 的教程将示例 Power BI 仪表板嵌入到 WPF 应用程序中.当我启动该应用程序时,我必须输入我的密码来验证我自己,当它尝试使用 getAppWorkspa
我们已将 TFS 2013 服务器升级到 TFS 2015,我们正在设置新的构建代理。 在此之前,我们进行了试运行,并在我们对现有 TFS 数据库进行最终转换之前让一切都运行良好。构建代理工作得很好。
我需要一些有关 Azure Durable Functions 的帮助。 我在 C# 中使用 VS Code 创建了一个新的持久函数,并通过 VS Code azure 函数扩展将其部署到 Azure
我是一名优秀的程序员,十分优秀!