「OSS」阿里云OSS之STS臨時訪問授權(quán)

前言

小白后臺僅僅只是一位小白Java

上一篇文章中,小白介紹了阿里云OSS有關(guān)自定義域名、證書托管的內(nèi)容,這一片文章我們將著重介紹一下阿里云OSS身份認證相關(guān)的內(nèi)容。

拓展開來說,我們這里介紹的 身份認證 機制其實也是貫穿于阿里云各個產(chǎn)品線的 訪問控制 機制,換句話說就是阿里云為客戶提供的 用戶身份管理資源訪問控制 服務,但是這里我們只介紹在阿里云OSS這個產(chǎn)品下如何配置和使用身份認證服務,不對阿里云的整套 訪問控制 服務做深入探討。

介紹

阿里云提供的 權(quán)限管理系統(tǒng)訪問控制服務 主要包含兩部分,RAM(Resource Access Management)和 STS(Security Token Service),RAM 主要的作用是控制賬號系統(tǒng)的權(quán)限,你可以使用 RAM 在主賬號的權(quán)限范圍內(nèi)創(chuàng)建子用戶,給不同的子用戶分配不同的權(quán)限從而達到授權(quán)管理的目的。STS 是一個安全憑證(Token)的管理系統(tǒng),你可以使用 STS 來完成對于臨時用戶的訪問授權(quán)。

RAM 和 STS 需要解決的一個核心問題是如何在不暴露主賬號的 AccessKey 的情況下安全的授權(quán)別人訪問,因為一旦主賬號的 AccessKey 暴露出去的話會帶來極大的安全風險,別人可以隨意操作該賬號下所有的資源,盜取重要信息等。

RAM 提供一種 長期有效 的權(quán)限控制機制,通過分出不同權(quán)限的 子賬號,將不同的權(quán)限分給不同的用戶,這樣一旦子賬號泄露也不會造成全局的信息泄露。但是,由于子賬號在一般情況下是長期有效的,因此,子賬號的 AccessKey 也是不能泄露的。

相對于 RAM 提供的長效控制機制,STS 提供的是一種 臨時訪問授權(quán) 。通過 STS 可以返回 臨時的 AccessKey 和 Token,這些信息可以直接發(fā)給臨時用戶用來訪問 OSS 。一般來說,從 STS 獲取的權(quán)限會受到更加嚴格的限制,并且擁有時間限制,因此這些信息泄露之后對于系統(tǒng)的影響也很小。

場景描述

使用阿里云OSS的過程中,一般大家對于 RAM 會比較了解和熟悉,通常的做法也都是在阿里云的 RAM訪問控制臺 為 OSS 服務單獨創(chuàng)建一個具備 OSS 相應訪問權(quán)限的 RAM子賬號,然后在之后的 API 調(diào)用過程中使用該 RAM子賬號 的 AccessKey 進行簽名等操作。

看起來這種通過 RAM子賬號 實現(xiàn)對 OSS 進行訪問控制的方式是挺安全的,那么這種方式有沒有什么缺陷呢?或者有沒有更加安全的方式?接下來我們先來給大家舉一個模擬場景的例子。

Example
某個阿里云用戶,名為 小白,其在 OSS 下有兩個私有的 Bucket,bucket-abucket-b 。小白對這兩個 Bucket 都擁有完全的權(quán)限。

為了避免阿里云主賬號的 AccessKey 泄露導致安全風險,小白使用 RAM 創(chuàng)建了兩個子賬號 小明小賢,小明對 bucket-a 擁有讀寫權(quán)限,小賢對 bucket-b 擁有讀寫權(quán)限。小明和小賢都擁有獨立的 AccessKey,這樣萬一某個子賬號泄露了也只會影響其中一個 Bucket,而且小白可以很方便的在控制臺取消泄露用戶的授權(quán)。

現(xiàn)在因為某些原因,需要授權(quán)給別人讀取 bucket-a 中的 Object,這種情況下不應該直接把 小明AccessKey 透露出去;那么,這個時候可以新建一個 角色,比如 Bucket-A-Reader,給這個角色賦予讀取 bucket-a權(quán)限。但是請注意,這個時候 Bucket-A-Reader 還是沒法直接用的,因為并不存在對應 角色 Bucket-A-ReaderAccessKey,Bucket-A-Reader 現(xiàn)在僅僅表示一個擁有訪問 bucket-a 權(quán)限的一個虛擬實體。

為了能獲取 臨時授權(quán),這個時候可以調(diào)用 STSAssumeRole 接口,告訴 STS ,子賬號 小明 將要扮演 Bucket-A-Reader 這個角色,如果成功,STS 會返回一個 臨時的 AccessKeyId 、AccessKeySecret 還有 SecurityToken 作為訪問憑證。將這個 臨時授權(quán)憑證 發(fā)給需要訪問的 臨時用戶 就可以獲得訪問 bucket-a 的臨時權(quán)限了,憑證過期的時間可以在調(diào)用 AssumeRole 接口的時候指定,最大不超過2小時。

STS臨時訪問授權(quán)

STS臨時訪問授權(quán) 還是少不了 RAM 機制的支撐,一般要實現(xiàn) STS 臨時訪問授權(quán)需要依次完成 創(chuàng)建RAM子賬號 > 創(chuàng)建自定義角色 > 創(chuàng)建自定義授權(quán)策略 > 自定義角色添加自定義授權(quán)策略 > 子賬號授權(quán)STS權(quán)限 > STS簽發(fā)臨時憑證

準備工作

1. 創(chuàng)建 RAM 子賬號

創(chuàng)建一個 RAM 子賬號 ram_test_app,不需要賦予任何權(quán)限,因為在扮演角色的時候會自動獲得被扮演角色的所有權(quán)限。

2. 創(chuàng)建角色

這里創(chuàng)建兩個角色,一個用于用戶讀取等操作,一個用于用戶上傳文件。

  • 打開訪問控制的管理控制臺,選擇 角色管理 > 新建角色 ;
  • 選擇角色類型,這里選擇用戶角色;
  • 填寫類型信息,因為角色是被阿里云賬號使用過的,因此選擇默認的即可;
  • 配置角色基本信息;
創(chuàng)建角色
配置角色

3. 自定義授權(quán)策略

創(chuàng)建完角色之后,角色是沒有任何權(quán)限的,因此這里和上文所述一樣需要新建一個自定義的授權(quán)策略。授權(quán)策略如下:

  // 該授權(quán)策略表示對ram-test-app擁有只讀權(quán)限
  {
    "Version": "1",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "oss:ListObjects",
          "oss:GetObject"
        ],
        "Resource": [
          "acs:oss:*:*:ram-test-app",
          "acs:oss:*:*:ram-test-app/*"
        ]
      }
    ]
  }
創(chuàng)建授權(quán)策略

4. 自定義角色授權(quán)

建立完成自定義授權(quán)策略后,即可在 角色管理 里面給自定義角色 RamTestAppReadOnly 添加上 ram-test-app 的只讀授權(quán)。

角色管理
添加授權(quán)策略

5. 再次添加角色&授權(quán)

按照上文同樣的方法,建立一個 RamTestAppWrite 的角色,并且賦予寫 ram-test-app 的自定義授權(quán),授權(quán)如下:

  {
    "Version": "1",
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "oss:DeleteObject",
          "oss:ListParts",
          "oss:AbortMultipartUpload",
          "oss:PutObject"
        ],
        "Resource": [
          "acs:oss:*:*:ram-test-app",
          "acs:oss:*:*:ram-test-app/*"
        ]
      }
    ]
  }

目前新建的兩個角色為:RamTestAppReadOnlyRamTestAppWrite,分別表示了對于 Bucket ram-test-app 的讀寫權(quán)限。

自定義角色

臨時授權(quán)訪問憑據(jù)

創(chuàng)建了角色之后,接下來就可以使用臨時授權(quán)來訪問OSS了。

在正式使用之前,還有一些工作需要完成。扮演角色 也是需要授權(quán)的,否則任意子賬號都可以扮演這些角色會帶來不可預計的風險,因此有扮演對應角色需求的子賬號需要顯式的配置權(quán)限。

1. 在授權(quán)管理策略中新建兩個自定義的授權(quán)策略,分別如下:

  {
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Effect": "Allow",
        "Resource": "acs:ram::1894******722283:role/ramtestappreadonly"
      }
    ],
    "Version": "1"
  }

使用相同的方法創(chuàng)建另一個自定義授權(quán)策略:

  {
    "Statement": [
      {
        "Action": "sts:AssumeRole",
        "Effect": "Allow",
        "Resource": "acs:ram::1894******722283:role/ramtestappwrite"
      }
    ],
    "Version": "1"
  }

這里 Resource 后面填寫的內(nèi)容表示某個角色 ID,角色的 ID 可以在 角色管理 > 角色詳情 中找到。

2. 將這兩個授權(quán)賦給 ram_test_app 這個賬號

現(xiàn)在一切準備就緒,可以正式使用STS來授權(quán)訪問了。

RAM進行STS臨時授權(quán)

這里小白給出基于 SpringBoot 的 Java SDK 源碼實現(xiàn)

  <!-- OSS Maven Dependency -->
  <dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.4.2</version>
  </dependency>
  public AssumeRoleResponse buildAliyunSTSCredentials() throws ClientException {
    // STS
    DefaultProfile.addEndpoint("", "", "Sts", "sts.cn-hangzhou.aliyuncs.com");
    IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
    DefaultAcsClient client = new DefaultAcsClient(profile);

    final AssumeRoleRequest request = new AssumeRoleRequest();
    request.setMethod(MethodType.POST);
    request.setProtocol(ProtocolType.HTTPS);
    request.setDurationSeconds(60 * 60 * 1L);
    request.setRoleArn("acs:ram::12************41:role/RamTestAppReadOnly");  // 要扮演的角色ID
    request.setRoleSessionName("external-username");
    // request.setPolicy(policy);

    // 生成臨時授權(quán)憑證
    final AssumeRoleResponse response = client.getAcsResponse(request);

    String appKey = response.getCredentials().getAccessKeyId();  // 臨時憑據(jù)AccessKeyId
    String appSecret = response.getCredentials().getAccessKeySecret();  // 臨時憑據(jù)AccessKeySecret
    String securityToken = response.getCredentials().getSecurityToken();  
    String expiration = response.getCredentials().getExpiration();
    return response;
  }

accessKeyId表示RAM子賬號的AccessKeyId;
accessKeySecret表示RAM子賬號的AccessKeySecret;
RoleArn表示的是需要扮演的角色ID,角色的ID可以在 角色管理 > 角色詳情 中找到;
RoleSessionName是一個用來標示臨時憑證的名稱,一般來說建議使用不同的應用程序用戶來區(qū)分;
DurationSeconds指的是臨時憑證的有效期,單位是s,最小為900,最大為3600;
Policy表示的是在扮演角色的時候額外加上的一個權(quán)限限制;
appKey表示創(chuàng)建的臨時憑據(jù)AccessKeyId;
appSecret表示創(chuàng)建的臨時憑據(jù)AccessKeySecret;

總結(jié)

其實實現(xiàn)STS臨時訪問授權(quán)的過程就是 創(chuàng)建RAM子賬號 > RAM子賬號授予STS權(quán)限 > RAM子賬號扮演指定角色,拿到臨時授權(quán)憑證就可以進行服務端相關(guān)的簽名/上傳等權(quán)限內(nèi)的操作了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容