【问题标题】:What domain is Google Cloud Storage expecting in the ACL definitions when inserting an object?插入对象时,谷歌云存储在 ACL 定义中期望什么域?
【发布时间】:2013-07-29 01:34:50
【问题描述】:

我正在使用谷歌存储 API 来保存和检索部署在 GAE 上的应用程序中的图像。我成功检索了图像,但在持久化时,我在详细信息中收到错误 400:

400 OK
{
    "code" : 400,
    "errors" : [ {
        "domain" : "global",
        "message" : "Required",
        "reason" : "required"
     }],
     "message" : "Required"
}

基于this information 我想我可能不需要它,所以我尝试不使用它。当我添加 apppot URL 时,我正在与谷歌云存储进行通信,我得到了这个:

400 OK
{
    "code" : 400,
    "errors" : [ {
        "domain" : "global",
        "message" : "Required",
        "reason" : "required"
     }, {
        "domain" : "global",
        "message" : "Could not find domain \"mydomain.appspot.com\".",
        "reason" : "invalid"
     } ],
     "message" : "Required"
}

我已按照以下步骤操作:

  1. 开启对 Google Cloud Service 的 JSON API 访问权限
  2. 创建了一个服务帐号
  3. 下载了p12文件
  4. 将 maven 配置为不对文件进行编码
  5. 配置 maven 以包含存储服务 api
  6. 使用服务帐户电子邮件地址作为服务帐户创建了一个 GoogleCredential,将 StorageScopes.DEVSTORAGE_FULL_CONTROL 添加到范围并链接到私钥文件 (p12)
  7. 使用上述凭据、http 传输等实例化了一个 Storage 对象

我正在使用在 StorageObject 对象上设置的 ObjectAccessControl 对象列表,如下所示:

...
//email from the service account client id configuration in the google cloud console
myAclList.add(new ObjectAccessControl()
            .setEntity("user-" + settings.getEmail()).setRole("OWNER")); 
//confused about what domain I should use; tried none, 
myAclList.add(new ObjectAccessControl()
            .setEntity("domain-" + settings.getDomain())
            .setRole("READER"));
StorageObject objectMetadata = new StorageObject()
            .setName("blahblah")
            .setAcl(myAclList)
            .setContentDisposition("attachment");
Storage.Objects.Insert insertObject = storage.objects()
            .insert(settings.getBucket(), objectMetadata, mediaContent);
insertObject.execute();  //400 error happens here
...

我究竟应该为域发送什么?我可能错过了在控制台中配置的东西吗?我没有想法。

非常感谢您的任何建议!

编辑:我使用的是 google-api-services-storage jar 的 v1beta2-rev2-1.15.0-rc 版本。

【问题讨论】:

  • 默认情况下,ACL 列表应设置为合理的默认值。如果您尝试完全省略 setAcl(),对您有用吗?
  • 删除 setAcl() 产生相同的结果。
  • 实际上,ObjectAccessControls doc 并没有说明将域设置为实体,只是组或用户,而域将被设置(如果可用),但 Object insert doc 中的示例显示域是在 ACL 中设置为实体。

标签: java google-app-engine google-cloud-storage service-accounts


【解决方案1】:

您看到“找不到域 \"mydomain.appspot.com\" 的原因。”是“域-”前缀是指 Google Apps for Business 域中的所有帐户,而不是 appengine 域名。例如,如果您为您的公司 fakecompany.com 使用 Google Apps,并且您想为 fakecompany.com 下的所有帐户授予对存储桶的读取访问权限,则可以指定“domain-fakecompany.com”来引用所有此类帐户。

我猜 mydomain.appspot.com 是 appengine 域名而不是 Google Apps for Business 域,这会导致此类错误。

更新:还有一个误解值得指出。服务帐户不一定有权将新对象插入到您拥有的存储桶中。确保它对存储桶具有明确的 WRITE 或更好的权限,或者,如果您使用的是默认存储桶 ACL,它至少是您项目的“编辑器”。

最后,确保您的存储桶名称和对象名称在插入对象时存在且不为空。这是一个非常容易遇到的问题,并且提供的错误消息并不总是很清楚。

【讨论】:

  • 所以我要做的就是将这个对象上传到 GCS 并让每个人都可以阅读。我想使用 JSON API 来做到这一点。我应该使用 StorageObject 构建器添加哪些 ACL 规则?我并不特别关心任何特定的域。我只是希望将所有者设置为服务帐户提供的电子邮件(上面代码中的前 2 行)并使其对所有人都可读,但是我似乎什至无法设置没有的 ACL域(参见第一个 JSON 错误)。始终需要域是否正确?如果是这样,如果应用在 GAE 上应该是什么?
  • 您应该在 ACL 规则中设置的唯一两个字段是“实体”和“角色”。要使每个人都可以阅读该对象,请使用“allUsers”的“实体”和“READER”的角色,仅此而已。上传对象的帐户将始终是隐式所有者,尝试显式更改是错误的。
  • 我删除了除 allUsers/READER ObjectAccessControl 条目之外的所有内容,但仍然收到“域”:“全局”、“消息”:“必需”。还有其他想法吗?我们正在获得一个 Premier 帐户,因此我们可以正式向 Google 发送问题 :) 但采购过程需要一个月左右的时间,我真的需要尽快完成 :(
  • Hrm...我认为 ACL 不是您的问题。日志记录是否为您提供发送到服务器的确切请求?我认为还有其他事情发生。
  • 此外,我收到了 403 .. 我认为服务帐户电子邮件地址将自动获得对与应用程序关联的所有存储桶的完整写入权限。需要特别授予这些权利。
猜你喜欢
  • 2017-06-12
  • 2013-04-22
  • 1970-01-01
  • 2015-02-03
  • 2019-08-14
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多