使用STS临时授权方案上传视频

使用STS临时授权可以有效避免RAM用户密码泄露导致的安全风险,本文介绍如何使用STS临时授权方案上传视频。

步骤一:创建RAM用户

说明
  • 下述步骤4中,建议您将登录名称设置为vod,本文后续描述都以登录名称vod为例。

  • 下述步骤5中,建议您访问方式选择OpenAPI调用访问方式。

  1. 使用阿里云账号(主账号)或RAM管理员登录RAM控制台

  2. 在左侧导航栏,选择身份管理 > 用户

  3. 用户页面,单击创建用户

  4. 创建用户页面的用户账号信息区域,设置用户基本信息。

    • 登录名称:可包含英文字母、数字、半角句号(.)、短划线(-)和下划线(_),最多64个字符。

    • 显示名称:最多包含128个字符或汉字。

    • 标签:单击edit,然后输入标签键和标签值。为RAM用户绑定标签,便于后续基于标签的用户管理。

    说明

    单击添加用户,可以批量创建多个RAM用户。

  5. 访问方式区域,选择访问方式,然后设置对应参数。

    为了账号安全,建议您只选择以下访问方式中的一种,将人员用户和应用程序用户分离,避免混用。

    • 控制台访问

      如果RAM用户代表人员,建议启用控制台访问,使用用户名和登录密码访问阿里云。您需要设置以下参数:

      • 控制台登录密码:选择自动生成密码或者自定义密码。自定义登录密码时,密码必须满足密码复杂度规则。更多信息,请参见设置RAM用户密码强度

      • 密码重置策略:选择RAM用户在下次登录时是否需要重置密码。

      • 多因素认证(MFA)策略:选择是否为当前RAM用户启用MFA。启用MFA后,主账号还需要为RAM用户绑定MFA设备或RAM用户自行绑定MFA设备。更多信息,请参见为RAM用户绑定MFA设备

    • OpenAPI调用访问

      如果RAM用户代表应用程序,建议启用OpenAPI调用访问,使用访问密钥(AccessKey)访问阿里云。启用后,系统会自动为RAM用户生成一个AccessKey ID和AccessKey Secret。更多信息,请参见创建AccessKey

      重要

      RAM用户的AccessKey Secret只在创建时显示,不支持查看,请妥善保管。

  6. 单击确定

  7. 根据界面提示,完成安全验证。

步骤二:为RAM用户授予调用STS服务AssumeRole接口的权限

  1. 在RAM控制台的用户页面,单击目标RAM用户(上述创建的vod用户)操作列的添加权限

  2. 新增授权面板,为RAM用户添加权限。

    说明

    vod用户添加调用STS服务AssumeRole接口的权限策略AliyunSTSAssumeRoleAccess,可通过在系统策略的搜索输入框中输入AliyunSTSAssumeRoleAccess查找。

    选择策略

    1. 选择资源范围。

    2. 选择授权主体。

      授权主体即需要添加权限的RAM用户。系统会自动选择当前的RAM用户。

    3. 选择权限策略。

      权限策略是一组访问权限的集合,分为以下两种。支持批量选中多条权限策略。

      • 系统策略:由阿里云创建,策略的版本更新由阿里云维护,用户只能使用不能修改。更多信息,请参见支持RAM的云服务

        说明

        系统会自动标识出高风险系统策略(例如:AdministratorAccess、AliyunRAMFullAccess等),授权时,尽量避免授予不必要的高风险权限策略。

      • 自定义策略:由用户管理,策略的版本更新由用户维护。用户可以自主创建、更新和删除自定义策略。更多信息,请参见创建自定义权限策略

    4. 单击确认新增授权

  3. 单击关闭

步骤三:创建RAM角色

说明

下述步骤5中,建议您将角色名称设置为vodrole,本文后续描述都以角色名称vodrole为例。

  1. 使用RAM管理员登录RAM控制台

  2. 在左侧导航栏,选择身份管理 > 角色

  3. 角色页面,单击创建角色

  4. 创建角色页面,选择可信实体类型为阿里云账号,然后单击下一步

  5. 设置角色信息。

    1. 输入角色名称

    2. 输入备注

    3. 选择信任的云账号。

      • 当前云账号:当您允许当前阿里云账号下的所有RAM用户扮演该RAM角色时,您可以选择当前云账号

      • 其他云账号:当您允许其他阿里云账号下的所有RAM用户扮演该RAM角色时,您可以选择其他云账号,然后输入其他阿里云账号(主账号)ID。该项主要针对跨阿里云账号的资源授权访问场景,相关教程,请参见跨阿里云账号的资源授权

        您可以在安全设置页面查看阿里云账号(主账号)ID。

      重要

      如果您仅允许指定的RAM用户扮演该RAM角色,而不是阿里云账号(主账号)下的所有RAM用户,您可以采取以下两种方式:

  6. 单击完成

  7. 单击关闭

步骤四:为RAM角色授予管理VOD的权限

  1. 在RAM控制台的角色页面,单击目标RAM角色(上述创建的vodrole角色)操作列的添加权限

  2. 新增授权面板,为RAM角色添加权限。

    说明
    • 为控制风险,建议采用最小权限。

    • 如需vodrole角色可以访问和管理视频点播的资源,则建议为vodrole角色添加可以管理和操作视频点播所有资源的系统策略权限AliyunVODFullAccess,可通过在系统策略的搜索输入框中输入AliyunVODFullAccess查找,更多有关视频点播系统策略的定义及权限信息请参见系统授权策略

    授权

    1. 选择资源范围。

    2. 选择授权主体。

      授权主体即需要添加权限的RAM用户。系统会自动选择当前的RAM用户。

    3. 选择权限策略。

      权限策略是一组访问权限的集合,分为以下两种。支持批量选中多条权限策略。

      • 系统策略:由阿里云创建,策略的版本更新由阿里云维护,用户只能使用不能修改。更多信息,请参见支持RAM的云服务

        说明

        系统会自动标识出高风险系统策略(例如:AdministratorAccess、AliyunRAMFullAccess等),授权时,尽量避免授予不必要的高风险权限策略。

      • 自定义策略:由用户管理,策略的版本更新由用户维护。用户可以自主创建、更新和删除自定义策略。更多信息,请参见创建自定义权限策略

    4. 单击确认新增授权

    完成授权后,会生成一条授权成功的记录。授权成功

  3. 单击关闭

步骤五:通过STS授权访问视频点播

说明

本文仅介绍通过调用API扮演RAM角色获取并使用安全令牌(STS Token)访问视频点播的方法。

使用创建的RAM用户调用STS APIAssumeRole - 获取扮演角色的临时身份凭证获得RAM角色的安全令牌(STS Token),并使用安全令牌访问视频点播API。

本文仅提供Java语言获取STS临时Token的代码示例,有关STS SDK的集成及其他语言的使用说明请参见STS SDK概览

Java代码示例

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;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoRequest;
import com.aliyuncs.vod.model.v20170321.CreateUploadVideoResponse;

/**
 * @author jack
 * @date 2020/5/25
 */
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());

            createUploadVideo(response.getCredentials().getAccessKeyId(), response.getCredentials().getAccessKeySecret(), response.getCredentials().getSecurityToken());
        } 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;
        }
    }

    static void createUploadVideo(String accessKeyId, String accessKeySecret, String token) {
        // 点播服务所在的Region,接入服务中心为上海,则填cn-shanghai
        String regionId = "cn-shanghai";
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);

        CreateUploadVideoRequest request = new CreateUploadVideoRequest();
        request.setSecurityToken(token);
        request.setTitle("t5");
        request.setFileName("D:\\TestVideo\\t4.mp4");
        request.setFileSize(10240L);

        try {
            CreateUploadVideoResponse response = client.getAcsResponse(request);
            System.out.println("CreateUploadVideoRequest, " + request.getUrl());
            System.out.println("CreateUploadVideoRequest, requestId:" + response.getRequestId());
            System.out.println("UploadAddress, " + response.getUploadAddress());
            System.out.println("UploadAuth, " + response.getUploadAuth());
            System.out.println("VideoId, " + response.getVideoId());
        } catch (ClientException e) {
            System.out.println("action, error:" + e);
            e.printStackTrace();
        }
    }
}