使用安全令牌(STS Token)可以有效避免RAM用户AK泄漏导致的安全风险。获取STS Token的过程较为复杂,您需要提前准备好RAM用户、RAM角色,并授予相应的权限,再使用RAM用户的AK作为凭证调用AssumeRole接口扮演RAM角色,才能从STS服务获取到STS Token。
步骤一:创建RAM用户
创建RAM用户,注意以下几点:
- 建议您将登录名称设置为vod,本文后续描述都以登录名称vod为例。 
- 访问方式设置允许使用永久AccessKey访问。 
- 妥善保管获取的AccessKey。 
步骤二:为RAM用户授予调用STS服务AssumeRole接口的权限
- 在RAM控制台的用户页面,单击目标RAM用户(上述创建的vod用户)操作列的添加权限。 
- 在新增授权面板,为RAM用户添加权限。 说明- 为vod用户添加调用STS服务AssumeRole接口的权限策略AliyunSTSAssumeRoleAccess,可通过在系统策略的搜索输入框中输入 - AliyunSTSAssumeRoleAccess查找。 - 选择资源范围。 - 账号级别:权限在当前阿里云账号内生效。 
- 资源组级别:权限在指定的资源组内生效。 重要- 指定资源组授权生效的前提是该云服务及资源类型已支持资源组,详情请参见支持资源组的云服务。资源组授权示例,请参见使用资源组限制RAM用户管理指定的ECS实例。 
 
- 选择授权主体。 - 授权主体即需要添加权限的RAM用户。系统会自动选择当前的RAM用户。 
- 选择权限策略。 - 权限策略是一组访问权限的集合,分为以下两种。支持批量选中多条权限策略。 
- 单击确认新增授权。 
 
- 单击关闭。 
步骤三:创建RAM角色
下述步骤5中,建议您将角色名称设置为vodrole,本文后续描述都以角色名称vodrole为例。
- 使用RAM管理员登录RAM控制台。 
- 在左侧导航栏,选择。 
- 在角色页面,单击创建角色。  
- 在创建角色页面,选择信任主体类型为云账号,然后设置具体的阿里云账号,最后单击确定。  - 当前云账号:当您允许当前阿里云账号下的所有RAM用户和RAM角色扮演当前正在创建的RAM角色时,您可以选择当前云账号。 
- 其他云账号:当您允许其他阿里云账号下的所有RAM用户和RAM角色扮演当前正在创建的RAM角色时,您可以选择其他云账号,然后输入其他阿里云账号(主账号)ID。该项主要针对跨阿里云账号的资源授权访问场景,相关教程,请参见跨阿里云账号的资源授权。您可以在安全设置页面查看阿里云账号(主账号)ID。 
 
- (可选)如果您想设置RAM角色只能被可信阿里云账号下的指定RAM用户或RAM角色扮演,您可以单击切换编辑器,在编辑器中修改RAM角色的信任策略。 - 编辑器支持可视化编辑和脚本编辑两种模式,您可以任选其一。以下示例表示当前创建的RAM角色只能被当前阿里云账号(AccountID=100******0719)下的RAM用户 - Alice扮演。- 可视化编辑 - 在主体中指定具体的RAM用户名称。   
- 脚本编辑 - 在 - Principal的- RAM字段中指定具体的RAM用户。- { "Version": "1", "Statement": [ { "Effect": "Allow", "Principal": { "RAM": "acs:ram::100******0719:user/Alice" }, "Action": "sts:AssumeRole" } ] }
 
- 在创建角色对话框,输入角色名称,然后单击确定。 
步骤四:为RAM角色授予管理VOD的权限
- 在RAM控制台的角色页面,单击目标RAM角色(上述创建的vodrole角色)操作列的新增授权。 
- 在新增授权面板,为RAM角色添加权限。 说明- 为控制风险,建议采用最小权限。 
- 如需vodrole角色可以访问和管理视频点播的资源,则建议为vodrole角色添加可以管理和操作视频点播所有资源的系统策略权限AliyunVODFullAccess,可通过在系统策略的搜索输入框中输入 - AliyunVODFullAccess查找,更多有关视频点播系统策略的定义及权限信息请参见系统授权策略。
  - 选择资源范围。 - 账号级别:权限在当前阿里云账号内生效。 
- 资源组级别:权限在指定的资源组内生效。 重要- 指定资源组授权生效的前提是该云服务及资源类型已支持资源组,详情请参见支持资源组的云服务。资源组授权示例,请参见使用资源组限制RAM用户管理指定的ECS实例。 
 
- 选择授权主体。 - 授权主体即需要添加权限的RAM用户。系统会自动选择当前的RAM用户。 
- 选择权限策略。 - 权限策略是一组访问权限的集合,分为以下两种。支持批量选中多条权限策略。 
- 单击确认新增授权。 
 - 完成授权后,会生成一条授权成功的记录。  
- 单击关闭。 
步骤五:扮演RAM角色并获取STS Token
使用RAM用户调用STS APIAssumeRole - 获取扮演角色的临时身份凭证获得RAM角色的安全令牌(STS Token)。您可以直接使用STS Token访问点播服务API,也可将STS Token下发到客户端完成客户端直传等操作。本文提供Java SDK示例,更多语言示例请参考STS SDK概览。
V1.0 SDK
在Maven中添加如下依赖信息:
<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>aliyun-java-sdk-sts</artifactId>
   <version>3.1.2</version>
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-core</artifactId>
  <version>4.7.3</version>
</dependency>
<dependency>
  <groupId>com.aliyun</groupId>
  <artifactId>aliyun-java-sdk-vod</artifactId>
  <version>2.16.32</version>
</dependency>package pop;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
public class TestStsService {
    public static void main(String[] args) {
        // 从环境变量中获取步骤一生成的RAM用户的访问密钥(AccessKey ID和AccessKey Secret)。
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // AssumeRole API 请求参数:RoleArn, RoleSessionName, Policy, and DurationSeconds
        // RoleArn需要通过步骤三在RAM控制台上获取
        String roleArn = "<role-arn>";
        // RoleSessionName 角色会话名称,自定义参数
        String roleSessionName = "session-name";
        // 定制你的policy
        String policy = "{\n" +
                "  \"Version\": \"1\",\n" +
                "  \"Statement\": [\n" +
                "    {\n" +
                "      \"Action\": \"vod:*\",\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("", 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;
        }
    }
}V2.0 SDK
在Maven中添加如下依赖信息:
<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>sts20150401</artifactId>
   <version>1.1.7</version>
</dependency>
<dependency>
   <groupId>com.aliyun</groupId>
   <artifactId>vod20170321</artifactId>
   <version>3.6.4</version>
</dependency>import com.aliyun.sts20150401.Client;
import com.aliyun.sts20150401.models.AssumeRoleRequest;
import com.aliyun.sts20150401.models.AssumeRoleResponse;
import com.aliyun.sts20150401.models.AssumeRoleResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
public class TestStsService {
    public static void main(String[] args) {
        // 从环境变量中获取步骤一生成的RAM用户的访问密钥(AccessKey ID和AccessKey Secret)。
        String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
        String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
        // AssumeRole API 请求参数:RoleArn, RoleSessionName, Policy, and DurationSeconds
        // RoleArn需要通过步骤三在RAM控制台上获取
        String roleArn = "<role-arn>";
        // RoleSessionName 角色会话名称,自定义参数
        String roleSessionName = "session-name";
        // 定制你的policy
        String policy = "{\n" +
                "  \"Version\": \"1\",\n" +
                "  \"Statement\": [\n" +
                "    {\n" +
                "      \"Action\": \"vod:*\",\n" +
                "      \"Resource\": \"*\",\n" +
                "      \"Effect\": \"Allow\"\n" +
                "    }\n" +
                "  ]\n" +
                "}";
        try {
            AssumeRoleResponse assumeRoleResponse = 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 (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn, String roleSessionName, String policy) throws Exception {
        Config config = new Config()
                // 从环境变量中获取AccessKey ID的值
                .setAccessKeyId(accessKeyId)
                // 从环境变量中获取AccessKey Secret的值
                .setAccessKeySecret(accessKeySecret);
        config.endpoint = "sts.cn-hangzhou.aliyuncs.com";
        Client client = new Client(config);
        AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
                .setRoleArn(roleArn)
                .setRoleSessionName(roleSessionName)
                .setPolicy(policy);
        RuntimeOptions runtime = new RuntimeOptions();
        return client.assumeRoleWithOptions(assumeRoleRequest, runtime);
    }
}