当前位置: 首页 > 知识库问答 >
问题:

使用auth scope访问Gmail API时拒绝访问https://mail.google.com/

冯宪
2023-03-14

我正在尝试使用Gmail REST API在Gmail邮箱中读/写电子邮件/文件夹。当添加以下Google auth作用域时,可以从Gmail REST API读取电子邮件,而不会出现任何问题:

https://apps-apis.google.com/a/feeds/compliance/audit/, https://www.googleapis.com/auth/admin.directory.user.readonly, https://www.googleapis.com/auth/gmail.readonly, https://www.googleapis.com/auth/admin.directory.group.member.readonly, https://www.googleapis.com/auth/admin.directory.group.readonly

注:参数https://www.googleapis.com/auth/gmail.readonly正确地允许一个人从邮箱中读取。

然而,我也需要能够删除电子邮件。因此,根据https://developers.google.com/gmail/api/auth/scopes?hl=ja的留档,在添加以下授权范围时,只需包括https://mail.google.com/来代替https://www.googleapis.com/auth/gmail.readonly.:

https://apps-apis.google.com/a/feeds/compliance/audit/https://www.googleapis.com/auth/admin.directory.user.readonlyhttps://mail.google.com/https://www.googleapis.com/auth/admin.directory.group.member.readonlyhttps://www.googleapis.com/auth/admin.directory.group.readonly

...输出的错误如下:

    2015-07-27 10:27:59 i.c.s.a.cv [DEBUG] failed get labels for user
    com.google.api.client.auth.oauth2.TokenResponseException: 403 Forbidden
    {
       "error" : "access_denied",
       "error_description" : "Requested client not authorized."
    }

当然,这在谷歌方面是不正确的?我错过了什么?文件有误吗?需要添加什么身份验证范围?

我正在与JavaGoogle API客户端库接口。请参阅:https://developers.google.com/api-client-library/java/google-api-java-client/reference/1.20.0/overview-summary

删除请求如下:

public void deleteMessages(Queue<String> messages, GoogleUserAdapter user) throws Exception {

    Gmail gmail = getService(user);

    JsonBatchCallback<Void> voidCallBack = new JsonBatchCallback<Void>() {
        @Override
        public void onSuccess(Void t, HttpHeaders responseHeaders) throws IOException {
            logger.debug("delete success");

        }
        @Override
        public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) throws IOException {
            logger.debug("failed to delete message:"+e.getMessage());
        }
    };
    while (!messages.isEmpty()) {
        if (Thread.currentThread().isInterrupted()) 
            throw new InterruptedException();

        BatchRequest batch = gmail.batch();
        for (int i = 0; i < MAX_REQUESTS; i++) {
            if (messages.isEmpty() || Thread.currentThread().isInterrupted()) 
                break;
            gmail.users().messages().delete(user.getId(), messages.poll()).queue(batch, voidCallBack);
        }

        batch.execute();
    }
}

凭证的创建如下所示:

   private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {

    Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
     Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
    Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");

    GoogleCredential credential = new GoogleCredential.Builder()
          .setTransport(httpTransport)
          .setJsonFactory(jsonFactory)
          .setServiceAccountId(connection.getServiceAccountId())
          .setServiceAccountScopes(
                    Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
                            "https://apps-apis.google.com/a/feeds/compliance/audit/",
                            DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY, 
                            DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
          .setServiceAccountUser(impersonateAccount)
          .setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
          .build();
    setHttpTimeout(credential);
    return credential;
}

删除时发生的确切错误是:

   failed to delete message:Insufficient Permission

杰米

共有2个答案

阳枫涟
2023-03-14
private GoogleCredential getCredentials(JsonFactory jsonFactory, HttpTransport httpTransport, String impersonateAccount) throws Exception {

    Preconditions.checkNotNull(Strings.emptyToNull(impersonateAccount), "Google impersonate account is null");
     Preconditions.checkNotNull(Strings.emptyToNull(connection.getServiceAccountId()), "Service Account Email address is null");
    Preconditions.checkNotNull(connection.getServiceAccountPrivateKey(), "Service Account Private Key is null");

    GoogleCredential credential = new GoogleCredential.Builder()
          .setTransport(httpTransport)
          .setJsonFactory(jsonFactory)
          .setServiceAccountId(connection.getServiceAccountId())
          .setServiceAccountScopes(
                    Arrays.asList(DirectoryScopes.ADMIN_DIRECTORY_USER_READONLY, GmailScopes.MAIL_GOOGLE_COM,
                            "https://apps-apis.google.com/a/feeds/compliance/audit/",
                            DirectoryScopes.ADMIN_DIRECTORY_GROUP_MEMBER_READONLY, 
                            DirectoryScopes.ADMIN_DIRECTORY_GROUP_READONLY))
          .setServiceAccountUser(impersonateAccount)
          .setServiceAccountPrivateKey(connection.getServiceAccountPrivateKey().getPrivateKey())
          .build();
    setHttpTimeout(credential);
    return credential;
}
奚英朗
2023-03-14

拒绝访问是由html" target="_blank">常量Gmail示波器中的输入错误造成的。MAIL_GOOGLE_COM由GOOGLE Java客户端API定义。

“不变的回报”https://mail.google.com“而不是”https://mail.google.com/“(应该如此)。在字符串末尾省略反斜杠将导致访问被拒绝。

因此,在上面的示例中,必须设置以下服务范围:

https://apps-apis.google.com/a/feeds/compliance/audit/","https://mail.google.com/“,DirectoryScopes.ADMIN\u DIRECTORY\u GROUP\u MEMBER\u READONLY,DirectoryScopes.ADMIN\u DIRECTORY\u USER\u READONLY,DirectoryScopes.ADMIN\u DIRECTORY\u GROUP\u READONLY”

(注:硬编码值为“https://mail.google.com/")

必须将以下字符串添加到Google Apps中的Manage API客户端访问页面:

https://apps-apis.google.com/a/feeds/compliance/audit/https://www.googleapis.com/auth/admin.directory.user.readonlyhttps://mail.google.com/https://www.googleapis.com/auth/admin.directory.group.member.readonlyhttps://www.googleapis.com/auth/admin.directory.group.readonly

我希望这对其他人有帮助!

 类似资料:
  • 问题内容: 我在使它工作时遇到问题。它接收一个字符串,其中包含几条信息。但是,当我尝试将String写入文件以跟踪程序随时间的变化时,我收到拒绝访问错误: 叠层纱 完整的堆栈跟踪: 58行: 问题答案: 您必须先创建文件夹。但是您不能调用file.mkdirs()-您需要调用file.getParentFile()。mkdirs()-否则,您将使用文件名创建一个文件夹(这将阻止您使用以下命令创建文

  • 当我创建新用户或授予现有特权,我得到了这个错误: 授予所有表上的权限ok(信息\u架构除外),在此表上我得到了拒绝访问错误。我怎么能修理?转储所有数据库,删除所有数据库,然后从转储还原?

  • 为什么当我试图创建InputStream时,下面的代码会给我一个File Not Found异常?我的inputdirectory定义为一个文件,其值为“D:\general\images\small_images”(不带引号),我的用户对该文件具有完全的写权限。我正在使用Windows7,并以管理员的身份运行eclipse IDE。 如有任何帮助,不胜感激。

  • 我找到了商店定位器的谷歌教程:https://developers.google.com/maps/articles/phpsqlsearch_v3#findnearsql MySQL表完成了,它在我的服务器上工作。我可以在phpmyadmin中正确地写入地址和执行操作 但是在“用PHP输出XML”的教程中,我不能继续了。 我已经创建了文件phpsqlsearch_dbinfo.php,把我的数据

  • 问题内容: 我得到以下IOException: 尝试运行以下代码时: 在我看来,由于某种原因,JVM无法创建新文件。如果文件已经存在,则代码可以很好地运行。是否存在某种访问文件来指示JVM是否可以创建新文件还是我只是在做错什么? 任何帮助深表感谢 :-) 我正在运行Java 1.4,并且已经在Windows XP中的JDeveloper中进行了测试。 问题答案: 问题在于这些调用彼此接替: 创建操

  • 我正在开发一个名为的简单mariaDB数据库,还有一个名为的mariaDB用户。我知道StackOverflow上有很多类似的帐户,但我使用的不是根帐户,而是具有最低权限的普通帐户。 我可以通过SSH访问终端中的数据库,如下所示: 但是,当我在localhost上执行JDBC代码时,访问将在行被拒绝: java JDBC代码是:(我已经删除了类中一些不必要的内容,但是如果我遗漏了任何重要的内容,请