首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与OAuth 2.0一起使用服务帐户

与OAuth 2.0一起使用服务帐户
EN

Stack Overflow用户
提问于 2021-03-25 08:16:12
回答 1查看 731关注 0票数 4

我是Google API的新手。我有一个谷歌工作空间帐户注册了自己的域名。我希望能够使用google对用户邮箱执行操作。我正在使用快速启动项目,并使用身份验证作为作用域。

我可以在我执行OAuth同意的用户帐户上执行操作。

看看这个例子

代码语言:javascript
运行
复制
 String user = "me";
            ListLabelsResponse listResponse = service.users()
           .labels().list(user).execute();

它使用"me“关键字作为用户,我想使用帐户中的一个用户并执行相同的操作。当我将"me“切换到我域中的一个用户时,我会得到以下内容。

代码语言:javascript
运行
复制
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"
}

据我所知,从上面我需要提供用户委托。用户委托需要一个服务帐户。所以我试着跟踪这个教程

我的代码最终成为

代码语言:javascript
运行
复制
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可以达到目的。当使用服务帐户时,我会得到以下错误

代码语言:javascript
运行
复制
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依赖性

代码语言:javascript
运行
复制
<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>
EN

回答 1

Stack Overflow用户

发布于 2021-03-25 08:50:22

首先,您需要了解gmail数据是私有用户数据,只有该数据的所有者才能访问该数据或用户授权访问该数据的应用程序。在gsuite域帐户的情况下,域管理员还可以向其他人授予模拟原始用户的权限,但模拟仍然是用户访问数据的方式。它就像它原来的用户。(理解这个概念很快就会很重要)

您需要理解的是,服务帐户只是一个虚拟用户。它有自己的谷歌驱动器帐户,谷歌日历帐户,它也可以发送电子邮件,就像它有一个gmail帐户。因此,与您一样,它在默认情况下只能访问自己的私有数据。

现在,使用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访问数据,以下命令是可互换的。

代码语言:javascript
运行
复制
service.users().messages().list("user@somedomain.what.ever")
service.users().messages().list("me")

除了第一个选项不是当前通过身份验证的用户的电子邮件地址或模拟用户之外,它将失败。通过模拟用户,您实际上就是那个用户,因此API将服务帐户视为"user@somedomain.what.ever",而不指定模拟,您只是普通的老服务帐户,只能访问他们的数据。

需要有一种方法来指定来自服务帐户的所有调用现在都代表这个用户,这就是为什么需要将setServiceAccountUser设置为您想要模拟的用户。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66795504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档