发送访问 OSS 的请求

您可以直接使用 OSS 提供的 RESTful API 接口访问或者使用对 API 接口进行完整封装的 SDK 开发包。而每一次向 OSS 的请求根据当前 Bucket 权限和操作不同要求用户进行身份验证或者直接匿名访问。对OSS 的资源访问的分类如下:

  • 按访问者的角色可分为拥有者访问和第三方用户访问。这里的拥有者指的是 Bucket 的 Owner,也称为开发者。第三方用户是指访问 Bucket 里资源的用户。
  • 按访问者的身份信息可分为匿名访问和带签名访问。对于 OSS 来说,如果请求中没有携带任何和身份相关的信息即为匿名访问。带签名访问指的是按照 OSS API 文档中规定的在请求头部或者在请求 URL 中携带签名的相关信息。

AccessKey 类型

目前访问 OSS 使用的 AK(AccessKey)有三种类型,具体如下:

  • 阿里云账号 AccessKey

    阿里云账号 AK 特指 Bucket 拥有者的 AK,每个阿里云账号提供的 AccessKey 对拥有的资源有完全的权限。每个阿里云账号能够同时拥有不超过5个 active 或者 inactive 的 AK 对(AccessKeyId 和 AccessKeySecret)。

    用户可以登录AccessKey 管理控制台,申请新增或删除 AK 对。

    每个 AK 对都有active/inactive两种状态。

    • Active 表明用户的 AK 处于激活状态,可以在身份验证的时候使用。
    • Inactive 表明用户的 AK 处于非激活状态,不能在身份验证的时候使用。
    说明 请避免直接使用阿里云账户的 AccessKey。
  • RAM 子账号 AccessKey

    RAM (Resource Access Management) 是阿里云提供的资源访问控制服务。RAM 账号 AK 指的是通过 RAM 被授权的 AK。这组 AK 只能按照 RAM 定义的规则去访问Bucket 里的资源。通过 RAM,您可以集中管理您的用户(比如员工、系统或应用程序),以及控制用户可以访问您名下哪些资源的权限。比如能够限制您的用户只拥有对某一个 Bucket 的读权限。子账号是从属于主账号的,并且这些账号下不能拥有实际的任何资源,所有资源都属于主账号。

  • STS 账号 AccessKey

    STS(Security Token Service)是阿里云提供的临时访问凭证服务。STS 账号 AK 指的是通过 STS 颁发的 AK。这组 AK 只能按照 STS 定义的规则去访问 Bucket 里的资源。

身份验证具体实现

目前主要有三种身份验证方式:

  • AK 验证
  • RAM 验证
  • STS 验证

当用户以个人身份向 OSS 发送请求时,其身份验证的实现如下:

  1. 用户将发送的请求按照OSS指定的格式生成签名字符串。
  2. 用户使用 AccessKeySecret 对签名字符串进行加密产生验证码。
  3. OSS 收到请求以后,通过 AccessKeyId 找到对应的 AccessKeySecret,以同样的方法提取签名字符串和验证码。
    • 如果计算出来的验证码和提供的一样即认为该请求是有效的。
    • 否则,OSS 将拒绝处理这次请求,并返回 HTTP 403错误。

对于用户来说可以直接使用 OSS 提供的 SDK,配合不同类型的 AccessKey 即可实现不同的身份验证。

权限控制

针对存放在 Bucket 的 Object 的访问,OSS 提供了多种权限控制,主要有:

  • Bucket级别权限
  • Object级别权限
  • 账号级别权限(RAM)
  • 临时账号权限(STS)

Bucket 级别权限

  • Bucket 权限类型
    OSS 提供 ACL(Access Control List)权限控制方法,OSS ACL提供Bucket级别的权限访问控制,Bucket 目前有三种访问权限:public-read-write,public-read 和 private,它们的含义如下:
    权限值 中文名称 权限对访问者的限制
    public-read-write 公共读写 任何人(包括匿名访问)都可以对该 Bucket 中的 Object 进行读/写/删除操作;所有这些操作产生的费用由该 Bucket 的 Owner 承担,请慎用该权限。
    public-read 公共读,私有写 只有该 Bucket 的 Owner 或者授权对象可以对存放在其中的 Object 进行写/删除操作;任何人(包括匿名访问)可以对 Object 进行读操作。
    private 私有读写 只有该 Bucket 的Owner 或者授权对象可以对存放在其中的 Object 进行读/写/删除操作;其他人在未经授权的情况下无法访问该 Bucket 内的 Object。
  • Bucket 权限设定和读取方法

    功能使用参考:

Object 级别权限

  • Object 权限类型

    OSS ACL 也提供 Object 级别的权限访问控制。目前 Object 有四种访问权限:private, public-read, public-read-write, default。Put Object ACL 操作通过 Put 请求中的“x-oss-object-acl”头来设置,这个操作只有 Bucket Owner 有权限执行。

    权限值 中文名称 权限对访问者的限制
    public-read-write 公共读写 该 ACL 表明某个 Object 是公共读写资源,即所有用户拥有对该 Object 的读写权限。
    public-read 公共读,私有写 该 ACL 表明某个Object 是公共读资源,即非 Object Owner 只有该 Object 的读权限,而 Object Owner 拥有该 Object 的读写权限。
    private 私有读写 该 ACL 表明某个Object 是私有资源,即只有该 Object 的 Owner 拥有该 Object 的读写权限,其他的用户没有权限操作该 Object。
    default 默认权限 该 ACL 表明某个Object 是遵循 Bucket读写权限的资源,即 Bucket 是什么权限,Object 就是什么权限。
    说明
    • 如果没有设置 Object 的权限,即 Object 的 ACL 为 default,Object 的权限和 Bucket 权限一致。
    • 如果设置了 Object 的权限,Object 的权限大于 Bucket 权限。举个例子,如果设置了 Object 的权限是 public-read,无论 Bucket 是什么权限,该 Object 都可以被身份验证访问和匿名访问。
  • Object 权限设定和读取方法

    功能使用参考:

账号级别权限(RAM)

  • 使用场景

    如果您购买了云资源,您的组织里有多个用户需要使用这些云资源,这些用户只能共享使用您的云账号 AccessKey。这里有两个问题:

    • 您的密钥由多人共享,泄露的风险很高。
    • 您无法控制特定用户能访问哪些资源(比如 Bucket)的权限。

    解决方法:在您的阿里云账号下面,通过 RAM 可以创建具有自己 AccessKey 的子用户。您的阿里云账号被称为主账号,创建出来的账号被称为子账号,使用子账号的 AccessKey 只能使用主账号授权的操作和资源。

  • 具体实现

    有关 RAM 详情,请参考RAM用户手册

    对于授权中需要的 Policy 的配置方式可以参考本章最后一节:RAM 和 STS 授权策略(Policy)配置。

临时账号权限(STS)

  • 使用场景

    对于您本地身份系统所管理的用户,比如您的 App 的用户、您的企业本地账号、第三方 App ,也有直接访问 OSS 资源的可能,将这部分用户称为联盟用户。此外,用户还可以是您创建的能访问您的阿里云资源的应用程序。

    对于这部分联盟用户,通过阿里云 STS (Security Token Service) 服务为阿里云账号(或 RAM 用户)提供短期访问权限管理。您不需要透露云账号(或 RAM 用户)的长期密钥(如登录密码、AccessKey),只需要生成一个短期访问凭证给联盟用户使用即可。这个凭证的访问权限及有效期限都可以由您自定义。您不需要关心权限撤销问题,访问凭证过期后会自动失效。

    用户通过STS生成的凭证包括安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)。使用AccessKey方法与您在使用阿里云账户或 RAM 用户 AccessKey 发送请求时的方法相同。此外还需要注意的是在每个向 OSS 发送的请求中必须携带安全令牌。

  • 具体实现

    STS 安全令牌、角色管理和使用相关内容详情,请参考 RAM 用户指南中的角色管理。关键是调用 STS 服务接口AssumeRole来获取有效访问凭证即可,也可以直接使用 STS SDK 来调用该方法。

RAM 和 STS 应用场景实践

对于不同的应用场景,涉及到的访问身份验证方式可能存在差异。下面以几种典型的应用场景来说明访问身份验证中几种使用方式。

以一个移动 App 举例。假设您是一个移动 App 开发者,打算使用阿里云 OSS 服务来保存App的终端用户数据,并且要保证每个 App 用户之间的数据隔离,防止一个 App 用户获取到其它 App 用户的数据。

  • 方式一:使用 AppServer 来做数据中转和数据隔离

    如上图所示,您需要开发一个 AppServer。只有 AppServer 能访问云服务,ClientApp 的每次读写数据都需要通过 AppServer,AppServer 来保证不同用户数据的隔离访问。

    对于该种使用方式,使用阿里云账号或者 RAM 账号提供的密钥来进行签名验证访问。建议您尽量不要直接使用阿里云账号(主账号)的密钥访问 OSS,避免出现安全问题。

  • 方式二:使用 STS 让用户直接访问 OSS

    STS 方案描述如下图所示:



    方案的详细描述如下:

    1. App 用户登录。App 用户和云账号无关,它是 App 的终端用户,AppServer 支持 App 用户登录。对于每个有效的 App 用户来说,需要 AppServer 能定义出每个 App 用户的最小访问权限。
    2. AppServer 请求STS服务获取一个安全令牌(SecurityToken)。在调用 STS 之前,AppServer 需要确定 App 用户的最小访问权限(用 Policy 语法描述)以及授权的过期时间。然后通过扮演角色(AssumeRole)来获取一个代表角色身份的安全令牌。
    3. STS返回给 AppServer 一个有效的访问凭证,包括一个安全令牌(SecurityToken)、临时访问密钥(AccessKeyId, AccessKeySecret)以及过期时间。
    4. AppServer 将访问凭证返回给 ClientApp。ClientApp 可以缓存这个凭证。当凭证失效时,ClientApp 需要向 AppServer 申请新的有效访问凭证。比如,访问凭证有效期为1小时,那么 ClientApp 可以每30分钟向 AppServer 请求更新访问凭证。
    5. ClientApp 使用本地缓存的访问凭证去请求 Aliyun Service API。云服务会感知 STS 访问凭证,并会依赖 STS 服务来验证访问凭证,正确响应用户请求。

RAM 和 STS 授权策略(Policy)配置

对于 RAM 或者 STS 授权中使用 Policy,详细规则如下。

  • 示例

    先看下面的一个 Policy 示例:

    {
        "Version": "1",
        "Statement": [
            {
                "Action": [
                    "oss:GetBucketAcl",
                    "oss:ListObjects"
                ],
                "Resource": [
                    "acs:oss:*:1775305056529849:mybucket"
                ],
                "Effect": "Allow",
                "Condition": {
                    "StringEquals": {
                        "acs:UserAgent": "java-sdk",
                        "oss:Prefix": "foo"
                    },
                    "IpAddress": {
                        "acs:SourceIp": "192.168.0.1"
                    }
                }
            },
            {
                "Action": [
                    "oss:PutObject",
                    "oss:GetObject",
                    "oss:DeleteObject"
                ],
                "Resource": [
                    "acs:oss:*:1775305056529849:mybucket/file*"
                ],
                "Effect": "Allow",
                "Condition": {
                    "IpAddress": {
                        "acs:SourceIp": "192.168.0.1"
                    }
                }
            }
        ]
    }

    这是一个授权的 Policy,用户用这样的一个 Policy 通过 RAM 或 STS 服务向其他用户授权。Policy 当中有一个 Statement(一条 Policy 当中可以有多条 Statement)。Statement 里面规定了相应的 Action、Resource、Effect 和 Condition。

    这条 Policy 把用户自己名下的mybucketmybucket/file*这些资源授权给相应的用户,并且支持 GetBucketAcl、GetBucket、PutObject、GetObject 和 DeleteObject 这几种操作。Condition 中的条件表示 UserAgent为 java-sdk,源IP为192.168.0.1的时候鉴权才能通过,被授权的用户才能访问相关的资源。Prefix 这个 Condition 是在 GetBucket(ListObjects)的时候起作用的,关于这个字段的解释详见 OSS的 API 文档。

  • 配置细则
    • Version

      Version 定义了 Policy 的版本,本文档中 sw2q 的配置方式,设置为1

    • Statement

      通过Statement描述授权语义,其中可以根据业务场景包含多条语义,每条包含对 Action、Effect、Resource 和 Condition 的描述。每次请求系统会逐条依次匹配检查,所有匹配成功的 Statement 会根据 Effect 的设置不同分为通过(Allow)、禁止(Deny),其中禁止(Deny)的优先。如果匹配成功的都为通过,该条请求即鉴权通过。如果匹配成功有一条禁止,或者没有任何条目匹配成功,该条请求被禁止访问。

    • Action

      Action 分为三大类:

      • Service 级别操作,对应的是 GetService 操作,用来列出所有属于该用户的 Bucket 列表。
      • Bucket 级别操作,对应类似于 oss:PutBucketAcl、oss:GetBucketLocation之类的操作,操作的对象是 Bucket,它们的名称和相应的接口名称一一对应。
      • Object 级别操作,分为 oss:GetObject、oss:PutObject、oss:DeleteObject和oss:AbortMultipartUpload,操作对象是 Object。

      如想授权某一类的 Object 的操作,可以选择这几种的一种或几种。另外,所有的 Action 前面都必须加上oss:,如上面例子所示。Action 是一个列表,可以有多个 Action。具体的 Action 和 API 接口的对应关系如下:

      • Service级别
        API Action
        GetService(ListBuckets) oss:ListBuckets
      • Bucket 级别
        API Action
        PutBucket oss:PutBucket
        GetBucket(ListObjects) oss:ListObjects
        PutBucketAcl oss:PutBucketAcl
        DeleteBucket oss:DeleteBucket
        GetBucketLocation oss:GetBucketLocation
        GetBucketAcl oss:GetBucketAcl
        GetBucketLogging oss:GetBucketLogging
        PutBucketLogging oss:PutBucketLogging
        DeleteBucketLogging oss:DeleteBucketLogging
        GetBucketWebsite oss:GetBucketWebsite
        PutBucketWebsite oss:PutBucketWebsite
        DeleteBucketWebsite oss:DeleteBucketWebsite
        GetBucketReferer oss:GetBucketReferer
        PutBucketReferer oss:PutBucketReferer
        GetBucketLifecycle oss:GetBucketLifecycle
        PutBucketLifecycle oss:PutBucketLifecycle
        DeleteBucketLifecycle oss:DeleteBucketLifecycle
        ListMultipartUploads oss:ListMultipartUploads
        PutBucketCors oss:PutBucketCors
        GetBucketCors oss:GetBucketCors
        DeleteBucketCors oss:DeleteBucketCors
        PutBucketReplication oss:PutBucketReplication
        GetBucketReplication oss:GetBucketReplication
        DeleteBucketReplication oss:DeleteBucketReplication
        GetBucketReplicationLocation oss:GetBucketReplicationLocation
        GetBucketReplicationProgress oss:GetBucketReplicationProgress
      • Object 级别
        API Action
        GetObject oss:GetObject
        HeadObject oss:GetObject
        PutObject oss:PutObject
        PostObject oss:PutObject
        InitiateMultipartUpload oss:PutObject
        UploadPart oss:PutObject
        CompleteMultipart oss:PutObject
        DeleteObject oss:DeleteObject
        DeleteMultipartObjects oss:DeleteObject
        AbortMultipartUpload oss:AbortMultipartUpload
        ListParts oss:ListParts
        CopyObject oss:GetObject,oss:PutObject
        UploadPartCopy oss:GetObject,oss:PutObject
        AppendObject oss:PutObject
        GetObjectAcl oss:GetObjectAcl
        PutObjectAcl oss:PutObjectAcl
        RestoreObject oss:RestoreObject
  • Resource

    Resource 指代的是 OSS 上面的某个具体的资源或者某些资源(支持*通配),resource的规则是acs:oss:{region}:{bucket_owner}:{bucket_name}/{object_name}。对于所有 Bucket 级别的操作来说不需要最后的斜杠和{object_name},即acs:oss:{region}:{bucket_owner}:{bucket_name}。Resource 也是一个列表,可以有多个 Resource。其中的 region 字段暂时不做支持,设置为*

  • Effect

    Effect 代表本条的Statement的授权的结果,分为 Allow 和 Deny,分别指代通过和禁止。多条 Statement 同时匹配成功时,禁止(Deny)的优先级更高。

    例如,期望禁止用户对某一目录进行删除,但对于其他文件有全部权限:
    {
      "Version": "1",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "oss:*"
          ],
          "Resource": [
            "acs:oss:*:*:bucketname"
          ]
        },
        {
          "Effect": "Deny",
          "Action": [
            "oss:DeleteObject"
          ],
          "Resource": [
            "acs:oss:*:*:bucketname/index/*",
          ]
        }
      ]
    }
  • Condition

    Condition 代表 Policy 授权的一些条件,上面的示例里面可以设置对于acs:UserAgent 的检查、acs:SourceIp 的检查、还有oss:Prefix这项用来在 GetBucket 的时候对资源进行限制。

    OSS 支持的 Condition 如下:

    condition 功能 合法取值
    acs:SourceIp 指定 ip 网段 普通的 ip,支持*通配
    acs:UserAgent 指定 http useragent 头 字符串
    acs:CurrentTime 指定合法的访问时间 ISO8601格式
    acs:SecureTransport 是否是 https 协议 “true”或者”false”
    oss:Prefix 用作 ListObjects 时的 prefix 合法的object name

更多示例

针对具体场景更多的授权策略配置示例,可以参考教程示例:控制存储空间和文件夹的访问权限OSS 授权常见问题

Policy 在线图形化便捷配置工具,请单击这里

使用 OSSBrowser 简化 Policy 授权,一键完成对子账号授予限定 Bucket 或限定目录的权限,详情参考 简化 Policy 授权

最佳实践