gpt4 book ai didi

gmail-api - Gmail Java API 将服务帐户与 OAuth 2.0 结合使用

转载 作者:行者123 更新时间:2023-12-04 12:56:17 27 4
gpt4 key购买 nike

我是 Google API 的新手。我有一个用自己的域注册的 google 工作区帐户。
我希望能够使用 google java api 对用户邮箱执行操作。
我正在使用 quick start 项目并使用身份验证作为范围。
我可以对我执行 OAuth 同意的用户帐户执行操作。
看例子

 String user = "me";
ListLabelsResponse listResponse = service.users()
.labels().list(user).execute();
它使用“我”关键字作为用户,我想使用帐户中的一个用户并执行相同的操作。
当我将“我”切换到我域中的用户之一时,我得到以下信息。
GET https://gmail.googleapis.com/gmail/v1/users/user@somedomain.what.ever/labels
{
"code" : 403,
"errors" : [ {
"domain" : "global",
"message" : "Delegation denied for admin@mirncast.uk",
"reason" : "forbidden"
} ],
"message" : "Delegation denied for admin@mirncast.uk",
"status" : "PERMISSION_DENIED"
}
据我了解,我需要提供 user delegation
用户委派需要服务帐户。
所以我试着按照这个 tutorial
我的代码最终为
Set<String> scope = Collections.singleton(GmailScopes.MAIL_GOOGLE_COM);

GoogleCredential credentialFromJson = GoogleCredential
.fromStream(new FileInputStream(
"/certificate.json"))
.createScoped(scope);

GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.setServiceAccountId(credentialFromJson.getServiceAccountId())
.setServiceAccountPrivateKey(credentialFromJson.getServiceAccountPrivateKey())
.setServiceAccountScopes(Collections.singleton(GmailScopes.MAIL_GOOGLE_COM))
.setServiceAccountUser("user@somedomain.what.ever")
//.setServiceAccountUser("service@custom-octagon-1234567.iam.gserviceaccount.com")
.build();


Gmail service = new Gmail.Builder(httpTransport, jsonFactory, credential).setApplicationName("remediation service").build();

String user = "user@somedomain.what.ever";
final var messagesResponse = service.users().messages().list(user).execute();
System.out.println(messagesResponse.getMessages().stream().map(message -> message.getId()).collect(Collectors.joining(",")));
这段代码有几个问题。
当我使用我试图访问的相同电子邮件地址设置 setServiceAccountUser 时,我才能够使其工作。从我的角度来看,以这种方式使用 API 违背了目的。
使用服务帐户时出现以下错误
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
GET https://gmail.googleapis.com/gmail/v1/users/hraman@gsuite-dev.mirncast.uk/messages
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Precondition check failed.",
"reason" : "failedPrecondition"
} ],
"message" : "Precondition check failed.",
"status" : "FAILED_PRECONDITION"
}
该示例使用了不推荐使用的 API GoogleCredential,我无法确定基于 OAuth2 身份验证的最新 API 是什么
我的 Maven 依赖项
<dependencies>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-gmail</artifactId>
<version>v1-rev20210301-1.31.0</version>
</dependency>
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.31.4</version>
</dependency>
</dependencies>

最佳答案

您首先需要了解 gmail 数据是私有(private)用户数据,只有该数据的所有者才能访问该数据,或者已被用户授权访问该数据的应用程序。以gsuite域账号为例,域管理员也可以授予其他人冒充原用户的权限,但冒充的仍然是访问数据的用户。它只是表现得像它的原始用户。 (理解这个概念很快就会很重要)
您需要了解服务帐户只是一个虚拟用户。它有自己的谷歌驱动器帐户和谷歌日历帐户,它还可以像拥有gmail帐户一样发送电子邮件。所以和你一样,它只能默认访问自己的私有(private)数据。
现在使用 gsuite 我们可以委派用户权限,允许他们冒充另一个用户“user@somedomain.what.ever”
所以它可以设置为允许 "service@custom-octagon-1234567.iam.gserviceaccount.com" 模拟 "user@somedomain.what.ever" 并代表他们执行操作。只有这样才能在代码中工作,您必须说明您当前正在模拟哪个用户,在这种情况下,我们使用 setServiceAccountUser 如果您不这样做,那么您只是 "service@custom-octagon-1234567.iam.gserviceaccount.com" 并且只能访问属于 "service@custom-octagon-1234567.iam.gserviceaccount.com" 的数据
至于使用 messages.list 访问数据,以下命令是可以互换的。

service.users().messages().list("user@somedomain.what.ever")
service.users().messages().list("me")
除了如果第一个选项不是当前经过身份验证的用户或模拟用户的电子邮件地址,它将失败。通过模拟用户,您实际上就是该用户,因此 API 将服务帐户视为 "user@somedomain.what.ever" 而不指定模拟,您只是普通的旧服务帐户,只能访问其数据。
需要有一种方法来指定来自服务帐户的所有调用现在都代表该用户,这就是为什么您需要将 setServiceAccountUser 设置为您希望模拟的用户。

关于gmail-api - Gmail Java API 将服务帐户与 OAuth 2.0 结合使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66795504/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com