背景信息
由于RAM用戶的權限啟用后一直有效,一旦AccessKey泄露,可能會導致安全風險。建議您使用STS臨時授權,通過自定義過期時間,并指定相對復雜的策略對不同的RAM角色進行限制,采取權限最小化原則,提高服務訪問的安全性。
步驟一:創建RAM用戶并授予AssumeRole接口的調用權限
使用阿里云賬號(主賬號)或RAM管理員登錄RAM控制臺。
在左側導航欄,選擇。
在用戶頁面,單擊創建用戶。
在創建用戶頁面的用戶賬號信息區域,設置用戶基本信息。
訪問方式選中OpenAPI 調用訪問。
單擊確定并完成手機驗證,系統會自動生成RAM用戶的AccessKey。
單擊操作列的復制,保存用戶登錄名稱、登錄密碼、AccessKey等用戶信息。
重要 請務必保存好登錄密碼和AccessKey信息(AccessKey ID和AccessKey Secret),否則后續無法查詢。
返回用戶列表頁面,單擊已創建RAM用戶操作列的添加權限。
在新增授權面板,為RAM用戶添加權限。
選擇授權應用范圍。
指定授權主體。
選擇權限策略。
在系統策略下輸入框中輸入AliyunSTS,選擇權限策略為AliyunSTSAssumeRoleAccess。
單擊確定新增授權,完成用戶授權。
步驟二:創建RAM角色并授予IMS操作權限
使用RAM管理員登錄RAM控制臺。
在左側導航欄,選擇。
在角色頁面,單擊創建角色。
在創建角色頁面,選擇可信實體類型為阿里云賬號,然后單擊下一步。
設置角色信息。
輸入角色名稱。
輸入備注。
選擇信任的云賬號。
當前云賬號:當您允許當前阿里云賬號下的所有RAM用戶扮演該RAM角色時,您可以選擇當前云賬號。
其他云賬號:當您允許其他阿里云賬號下的所有RAM用戶扮演該RAM角色時,您可以選擇其他云賬號,然后輸入其他阿里云賬號(主賬號)ID。該項主要針對跨阿里云賬號的資源授權訪問場景,相關教程,請參見跨阿里云賬號的資源授權。
您可以在安全設置頁面查看阿里云賬號(主賬號)ID。
重要 如果您僅允許指定的RAM用戶扮演該RAM角色,而不是阿里云賬號(主賬號)下的所有RAM用戶,您可以采取以下兩種方式:
單擊完成,單擊為角色授權。
在新增授權面板,為RAM角色授權。
選擇授權范圍。
指定授權主體。
授權主體即需要授權的RAM角色,系統會自動填入當前的RAM角色,您也可以添加其他RAM角色。
選擇權限策略。
單擊確定,完成角色授權。
步驟三:使用創建的RAM用戶調用AssumeRole接口獲取臨時AccessKey
下載并集成STS SDK。下載地址,請參見STS SDK概覽。
調用AssumeRole獲取扮演角色的臨時身份憑證。
本文以Java示例代碼舉例說明,其他端代碼請參見SDK示例代碼。
Java
import com.aliyun.credentials.Client;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyun.teaopenapi.models.Config;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
/**
* @author xxx
* @date 2022/12/25
*/
public class TestStsService {
public static void main(String[] args) throws Exception {
// 只有RAM用戶(子賬號)才能調用 AssumeRole 接口
// 阿里云主賬號的AccessKeys不能用于發起AssumeRole請求
// 阿里云賬號AccessKey擁有所有API的訪問權限,建議您使用RAM用戶進行API訪問或日常運維。
// 本示例以將AccessKey ID和 AccessKey Secret保存在環境變量為例說明。
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// 如需硬編碼AccessKey ID和AccessKey Secret,代碼如下,但強烈建議不要把AccessKey ID和AccessKey Secret保存到工程代碼里,否則可能導致AccessKey泄露,威脅您賬號下所有資源的安全。
// config.accessKeyId = <yourAccessKeyId>;
// config.accessKeySecret = <yourAccessKeySecret>;
// AssumeRole API 請求參數:RoleArn, RoleSessionName, Policy, and DurationSeconds
// RoleArn 需要在 RAM 控制臺上獲取
//String roleArn = "<role-arn>";
String roleArn = "<role-arn>";
// RoleSessionName 是臨時Token的會話名稱,自己指定用于標識你的用戶,主要用于審計,或者用于區分Token頒發給誰
// 但是注意RoleSessionName的長度和規則,不要有空格,只能有'-' '_' 字母和數字等字符
// 具體規則請參考API文檔中的格式要求
String roleSessionName = "session-name";// 自定義即可
// 定制你的policy
String policy = "{\n" +
" \"Version\": \"1\",\n" +
" \"Statement\": [\n" +
" {\n" +
" \"Action\": \"ice:*\",\n" +
" \"Resource\": \"*\",\n" +
" \"Effect\": \"Allow\"\n" +
" }\n" +
" ]\n" +
"}";
try {
AssumeRoleResponse response = assumeRole(accessKeyId, accessKeySecret, roleArn, roleSessionName, policy);
System.out.println("Expiration: " + response.getCredentials().getExpiration());
System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
System.out.println("RequestId: " + response.getRequestId());
} catch (ClientException e) {
System.out.println("Failed to get a token.");
System.out.println("Error code: " + e.getErrCode());
System.out.println("Error message: " + e.getErrMsg());
}
}
static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn, String roleSessionName, String policy) throws ClientException {
try {
//構造default profile(參數留空,無需添加Region ID)
/*
說明:當設置SysEndpoint為sts.aliyuncs.com時,regionId可填可不填;反之,regionId必填,根據使用的服務區域填寫,例如:cn-shanghai
詳情參考STS各地域的Endpoint,請參見接入地址。
*/
IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKeyId, accessKeySecret);
//用profile構造client
DefaultAcsClient client = new DefaultAcsClient(profile);
// 創建一個 AssumeRoleRequest 并設置請求參數
final AssumeRoleRequest request = new AssumeRoleRequest();
request.setSysEndpoint("sts.aliyuncs.com");
request.setSysMethod(MethodType.POST);
request.setRoleArn(roleArn);
request.setRoleSessionName(roleSessionName);
request.setPolicy(policy);
// 發起請求,并得到response
final AssumeRoleResponse response = client.getAcsResponse(request);
return response;
} catch (ClientException e) {
throw e;
}
}
}
后續步驟
獲取到AccessKey信息后,您可以根據實際需求安裝完服務端SDK后調用OpenAPI,實現業務功能。詳情請參見調用OpenAPI流程。