【问题标题】:How to correctly obtain user's Calendar events using service account?如何使用服务帐户正确获取用户的日历事件?
【发布时间】:2013-06-20 10:04:00
【问题描述】:

我正在尝试为域中的用户检索日历事件。我有服务帐户访问权限,但是当我尝试获取特定用户事件时出现 404 错误。 下面是连接代码:

NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    GoogleCredential credential = new GoogleCredential.Builder()
            .setTransport(httpTransport)
            .setJsonFactory(JSON_FACTORY)
            .setServiceAccountId(googleApiServiceAccountId)
            .setServiceAccountScopes(Collections.singleton(CalendarScopes.CALENDAR_READONLY))
            .setServiceAccountPrivateKey(SecurityUtils.loadPrivateKeyFromKeyStore(
                    SecurityUtils.getPkcs12KeyStore(),
                    getClass().getClassLoader().getResourceAsStream(googleApiPrivateKeyPath),
                    NOTASECRET, PRIVATEKEY, NOTASECRET))
            .build();

    calendarApi = new Calendar.Builder(httpTransport,
            JSON_FACTORY, credential).setApplicationName(getApplicactionName()).build();

事件列表方法:

public List<Event> getCalendarEventsForUserAndDates(String userEmail, Long dateFrom, Long dateTo) {
    try {
        String pageToken = null;
        List<Event> allEvents = Lists.newArrayList();
        do {
            ArrayMap<String, Object> parameters = new ArrayMap<String, Object>();
            parameters.add("xoauth_requestor_id", userEmail);
            Calendar.Events.List list = calendarApiBean.getCalendarApi()
                    .events().list("primary");
            list.setTimeMax(new DateTime(dateFrom, 0))
                    .setTimeMin(new DateTime(dateTo, 0))
                    .setUnknownKeys(parameters);
            Events events = list.setPageToken(pageToken)
                    .execute();
            List<? extends Event> items = events.getItems();
            if (items != null) {
                allEvents.addAll(items);
            }
            pageToken = events.getNextPageToken();
        } while (pageToken != null);
        return allEvents;
    } catch (IOException e) {
        logger.error("error while retriving calendar events for {} and dates {} {} ", userEmail, dateFrom, dateTo);
        logger.error("exception", e);
        return Collections.emptyList();
    }

}

当我尝试将 xoauth_requestor_id 设置为用户的电子邮件并列出“主要”时,我会收到我的服务帐户的日历事件。当我将 events().list() 参数更改为用户的电子邮件时,我收到以下错误:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
  "code" : 404,
  "errors" : [ {
    "domain" : "global",
    "message" : "Not Found",
    "reason" : "notFound"
  } ],
  "message" : "Not Found"
}

感谢您的帮助。

【问题讨论】:

    标签: java google-calendar-api google-api-java-client


    【解决方案1】:

    为了解决这个问题,我必须将此服务帐户添加到域管理上的授权 API 客户端。 客户名称是服务帐户客户 ID,范围是只读日历

    【讨论】:

    • +1 但您能否详细说明所需的步骤。我还不能在(新的)Google Developers Console 中实现这一点。
    • 这不是我做的。一些域管理员修复了这个问题。
    • 嗨@mihn,你能分享完整的代码吗?我在开发可以使用服务帐户获取用户日历事件的程序时遇到了麻烦。我想知道我错过了什么。我想更正程序。谢谢。
    • 我相信@mihn 指的是“OAuth:管理 API 客户端访问”,它需要 G Suite 超级管理员访问权限。 support.google.com/a/answer/162106?hl=en
    【解决方案2】:

    这由两个不同的部分组成

    1. 创建服务帐号
    2. 授予它访问所需范围的权限

    创建服务帐号:

    1. 转到云页面来管理您的服务帐户: 左侧菜单 -> IAM & admin -> 服务帐户。或点击此链接:https://console.cloud.google.com/iam-admin/serviceaccounts
    2. 确保您以要使用的用户身份登录,并检查是否正确选择了组织
    3. 创建一个具有 Project Viewer 角色的新服务帐户(您可以稍后更改),并在单击创建密钥时下载带有凭据的 .json 文件。
    4. 编辑服务帐户并启用 G Suite 域范围委派
    5. 记下客户端 ID。 (不是密钥 ID)

    授予它权限:

    1. 转到 admin.google.com
    2. 确保您以具有管理员权限的用户身份登录。
    3. 然后进入安全 -> 设置 -> 高级设置 -> 管理 API 客户端访问
    4. 在客户端名称中填写您在上面复制的客户端 ID(不是密钥 ID)
    5. 填写您需要的范围并授权服务帐户。即:

      https://www.googleapis.com/auth/calendar.readonly,https://www.googleapis.com/auth/gmail.readonly
      

    我测试了我在源代码中链接的 Python 示例,并且可以确认它按预期工作。

    来源: https://developers.google.com/identity/protocols/OAuth2ServiceAccount https://support.google.com/a/answer/162106?hl=en

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多