尝试从Google Cloud Storage访问文件时如何修复403“访问被拒绝”响应

时间:2019-01-02 20:17:20

标签: python django google-app-engine google-cloud-storage django-storage

问题

当尝试从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映射。所有其他Bootstrap资源加载没有问题。我尝试过:

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

上一次修复尝试(#6)确实允许访问字形,但不是可接受的解决方案。

代码

settings.py中的静态文件路径/ GCP配置:

# 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响应代码。感谢您提供的所有帮助以及改进我的问题的建议。谢谢!

0 个答案:

没有答案