首页 > 解决方案 > 尝试从 Google Cloud Storage 访问文件时如何修复 403“拒绝访问”响应

问题描述

问题

尝试从 Google Cloud Storage 存储桶加载我的 Web 应用程序的静态内容时,少数文件返回 403 响应代码,而所有其他文件均已成功下载。

设置

该应用程序是托管在 Google App Engine 上的由 Django 提供支持的 (2.1.3) Python (3.7) 应用程序,使用已在 IAM 中获得编辑权限的服务帐户凭据。我们的前端使用 Bootstrap 3.3.7,将其源文件托管在我们的 GCS 存储桶中,并使用 django-storages (1.7.1) 插件与 GCS API 进行交互。

麻烦的文件是 Bootstrap 提供的 Glyphicon 图像,以及 CSS 映射。所有其他引导资源加载都没有问题。我试过了:

  1. 为服务帐号提供多种 IAM 权限组合
  2. 重新创建服务帐户和我们用来对其进行身份验证的密钥文件
  3. 禁用和重新启用 Google Cloud Storage API
  4. 使用服务帐户凭据创建新存储桶并重新加载所有静态文件
  5. 授予 AllUsers 对有问题文件的读取权限(因为当前设置了策略)
  6. 授予 AllUsers 对整个存储桶的读取权限

最后一次修复尝试(#6)确实启用了对字形图标的访问,但不是一个可接受的解决方案。

编码

我们的静态文件路径/GCP 配置settings.py

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
# If on GAE, use STATIC_ROOT; local, use STATICFILES_DIRS
STATIC_URL = '/static/'
if os.getenv('GAE_ENV', '').startswith('standard'):
    STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
else:
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static/')]

# Media url
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media/')

# Google Cloud Platform Settings (Storage & Authentication)
# Authentication
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = os.path.join(BASE_DIR, 'conf/vwa.json')
GS_CREDENTIALS = service_account.Credentials.from_service_account_file(
os.path.join(BASE_DIR, 'conf/vwa.json')
)
# File Storage
DEFAULT_FILE_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'
GS_BUCKET_NAME = os.getenv('GS_BUCKET_NAME', '')
# Static Storage
STATICFILES_STORAGE = 'storages.backends.gcloud.GoogleCloudStorage'

存储桶的 IAM 策略:

{
  "bindings": [
    {
      "members": [
        "serviceAccount:SERVICEACCOUNTADDRESS"
      ], 
      "role": "roles/storage.admin"
    }, 
    {
      "members": [
        "projectEditor:PROJECTNAME", 
        "projectOwner:PROJECTNAME"
      ], 
      "role": "roles/storage.legacyBucketOwner"
    }, 
    {
      "members": [
        "projectViewer:PROJECTNAME"
      ], 
      "role": "roles/storage.legacyBucketReader"
    }
  ], 
  "etag": "CAI="
}

存储桶的 ACL 策略:

[
  {
    "entity": "project-editors-649435531377",
    "projectTeam": {
      "projectNumber": "649435531377",
      "team": "editors"
    },
    "role": "OWNER"
  },
  {
    "entity": "project-owners-649435531377",
    "projectTeam": {
      "projectNumber": "649435531377",
      "team": "owners"
    },
    "role": "OWNER"
  },
  {
    "entity": "project-viewers-649435531377",
    "projectTeam": {
      "projectNumber": "649435531377",
      "team": "viewers"
    },
    "role": "READER"
  }
]

字形图标的 IAM 政策:

{
  "bindings": [
    {
      "members": [
        "projectOwner:PROJECTNAME", 
        "projectEditor:PROJECTNAME", 
        "serviceAccount:SERVICEACCOUNTADDRESS", 
        "allUsers"
      ], 
      "role": "roles/storage.legacyObjectOwner"
    }, 
    {
      "members": [
        "projectViewer:PROJECTNAME", 
        "allAuthenticatedUsers"
      ], 
      "role": "roles/storage.legacyObjectReader"
    }
  ], 
  "etag": "CAQ="
}

字形图标的 ACL 策略:

[
  {
    "entity": "project-owners-649435531377",
    "projectTeam": {
      "projectNumber": "649435531377",
      "team": "owners"
    },
    "role": "OWNER"
  },
  {
    "entity": "project-editors-649435531377",
    "projectTeam": {
      "projectNumber": "649435531377",
      "team": "editors"
    },
    "role": "OWNER"
  },
  {
    "entity": "project-viewers-649435531377",
    "projectTeam": {
      "projectNumber": "649435531377",
      "team": "viewers"
    },
    "role": "READER"
  },
  {
    "email": "SERVICEACCOUNTADDRESS",
    "entity": "user-SERVICEACCOUNTADDRESS",
    "role": "OWNER"
  },
  {
    "entity": "allAuthenticatedUsers",
    "role": "READER"
  },
  {
    "entity": "allUsers",
    "role": "OWNER"
  }
]

我希望应该正确下载有问题的文件,但实际行为是 403 响应代码。我感谢任何和所有帮助,以及改进我的问题的建议。谢谢!

标签: pythondjangogoogle-app-enginegoogle-cloud-storagedjango-storage

解决方案


推荐阅读