在移动端或Web端访问服务时,您可以使用STS临时授权,可以有效避免RAM用户密码泄露导致的安全风险。通过阅读本文,您可以了解STS授权的方法。

背景信息

由于RAM用户的权限启用后一直有效,一旦AccessKey泄露,可能会导致安全风险。建议您使用STS临时授权,通过自定义过期时间,并指定相对复杂的策略对不同的RAM角色进行限制,采取权限最小化原则,提高服务访问的安全性。

步骤一:创建RAM用户并授予AssumeRole接口的调用权限

  1. 使用阿里云账号登录RAM控制台
  2. 在左侧导航栏,选择身份管理 > 用户
  3. 用户页面,单击创建用户
  4. 创建用户页面的用户账号信息区域,设置用户基本信息。
    • 登录名称:可包含英文字母、数字、半角句号(.)、短划线(-)和下划线(_),最多64个字符。
    • 显示名称:最多包含128个字符。
    • 可选:标签:您可以单击edit,然后输入标签键和标签值。为RAM用户绑定标签,便于后续基于标签的用户管理。
    说明 单击添加用户,可以批量创建多个RAM用户。
  5. 访问方式选中OpenAPI 调用访问
  6. 单击确定并完成手机验证,系统会自动生成RAM用户的AccessKey。
    001
  7. 单击操作列的复制,保存用户登录名称、登录密码、AccessKey等用户信息。
    重要 请务必保存好登录密码和AccessKey信息(AccessKey ID和AccessKey Secret),否则后续无法查询。
  8. 返回用户列表页面,单击已创建RAM用户操作列的添加权限
  9. 添加权限面板,为RAM用户添加权限。
    1. 选择授权应用范围。

      授权范围选择整个云账号,智能媒体服务暂不支持指定资源组授权。关于资源组详情,请参见资源目录、资源组与标签的区别和联系

    2. 输入授权主体。
      授权主体即需要添加权限的RAM用户。
    3. 选择权限策略。

      系统策略下输入框中输入AliyunSTS,选择权限策略为AliyunSTSAssumeRoleAccess

    4. 单击确定,完成用户授权。

步骤二:创建RAM角色并授予IMS操作权限

  1. 使用阿里云账号登录RAM控制台
  2. 在左侧导航栏,选择身份管理 > 角色
  3. 角色页面,单击创建角色
  4. 创建角色面板,选择可信实体类型为阿里云账号,然后单击下一步
  5. 设置角色信息。
    1. 输入角色名称
    2. 可选:输入备注
    3. 选择云账号。
      • 当前云账号:当您允许当前阿里云账号下的RAM用户扮演该RAM角色时,您可以选择当前云账号
      • 其他云账号:当您允许其他阿里云账号下的RAM用户扮演该RAM角色时,您可以选择其他云账号,然后输入其他阿里云账号ID。该项主要针对跨阿里云账号的资源授权访问场景。
        说明 您可以访问安全设置页面查看阿里云账号ID。
  6. 单击完成
  7. 单击完成,单击为角色授权
  8. 添加权限面板,为RAM角色添加权限。
    1. 选择授权范围。

      授权范围选择整个云账号,智能媒体服务暂不支持指定资源组授权。关于资源组详情,请参见资源目录、资源组与标签的区别和联系

    2. 输入授权主体。
      授权主体即需要授权的RAM角色,系统会自动填入当前的RAM角色,您也可以添加其他RAM角色。
    3. 选择权限策略。
      • 使用系统策略

        系统策略下输入框中输入AliyunICE,根据实际需求选择筛选出的权限策略。

        权限策略描述OpenAPI调用权限
        AliyunICEFullAccess管理和操作IMS所有资源的权限。可以调用智能媒体服务所有的OpenAPI。
        AliyunICEReadOnlyAccess只读访问IMS所有资源的权限。可以调用智能媒体服务所有读取类的OpenAPI,例如Get、Describe、Search、List开头的接口。
      • 使用自定义策略

        自定义策略下根据实际需求选择权限策略。如果没有可用的自定义权限策略, 单击新建权限策略,详情请参见创建自定义权限策略自定义策略示例

      说明
      • 每次最多绑定5条策略,如需绑定更多策略,请分次操作。
      • 为控制风险,建议采用最小权限原则。
      • 如果需要使用智能媒体服务端侧(iOS或Android)SDK,由于需要将文件上传到OSS上,因此需要增加OSS的权限,即AliyunOSSFullAccess,或者您可以根据实际情况自定义OSS的权限策略。
    4. 单击确定,完成角色授权。

步骤三:使用创建的RAM用户调用AssumeRole接口获取临时AccessKey

  1. 下载并集成STS SDK。下载地址,请参见STS SDK概览
  2. 调用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流程

相关参考

AssumeRole - 获取扮演角色的临时身份凭证