全部产品
存储与CDN 数据库 安全 应用服务 数加·人工智能 数加·大数据基础服务 互联网中间件 视频服务 开发者工具 解决方案 物联网
视频点播

STS临时授权访问

更新时间:2017-07-24 14:17:52

基本概念

以下是一些基本概念的简单解释:

  • 子账号:从阿里云的主账号中创建出来的子账号,在创建的时候可以分配独立的密码和权限,每个子账号拥有自己AccessKey,可以和阿里云主账号一样正常的完成有权限的操作。一般来说,这里的子账号可以理解为具有某种权限的用户,可以被认为是一个具有某些权限的操作发起者。
  • 角色(Role):表示某种操作权限的虚拟概念,但是没有独立的登录密码和AccessKey。子账号可以扮演角色,扮演角色的时候的权限是该角色自身的权限。
  • 授权策略(Policy):用来定义权限的规则,比如允许用户上传、播放。

子账号和角色可以类比为某个个人和其身份的关系,某人在公司的角色是员工,在家里的角色是父亲,在不同的场景扮演不同的角色,但是还是同一个人。在扮演不同的角色的时候也就拥有对应角色的权限。单独的员工或者父亲概念并不能作为一个操作的实体,只有有人扮演了之后才是一个完整的概念。这里还可以体现一个重要的概念,那就是角色可以被多个不同的个人同时扮演。完成角色扮演之后,该个人就自动拥有该角色的所有权限。

使用场景

之前章节只用到了RAM的子账号功能,这些子账号都是可以长期正常使用的,发生泄露之后如果无法及时解除权限的话会很危险。

用户自己部署服务器生成STS临时AK,可以自定义过期时间并且指定复杂的策略来对不同的子账号进行限制,仅提供最小的权限。

创建角色

创建角色的步骤如下:

  1. 按照上文的流程创建一个子账号ram_test,不需要赋予任何权限,因为在扮演角色的时候会自动获得被扮演角色的所有权限。
  2. 创建角色。这里创建两个角色,一个用于只读访问VOD所有资源等操作,一个用于用户上传文件。

    1. 打开访问控制的管理控制台,选择 角色管理 > 新建角色创建角色1
    2. 选择角色类型。这里选择 用户角色

      创建角色2

    3. 填写类型信息。因为角色是被阿里云账号使用过的,因此选择默认的即可。

      创建角色3

    4. 配置角色基本信息。

      创建角色4

  3. 创建完角色之后,角色是没有任何权限的,因此需要在角色管理里面给RamTestReadOnly添加上AliyunVODReadOnlyAccess的系统授权。角色授权1角色授权2

  4. 按照上文同样的方法,建立一个RamTestUpload的角色,并且赋予AliyunVODUploadAuth的系统授权。

现在我们新建好了两个角色:RamTestReadOnly和RamTestUpload,分别表示了只读访问VOD所有资源的权限和使用VOD上传的权限。角色授权3

临时授权访问

创建了角色之后,接下来就可以使用临时授权来访问点播VOD了。

准备工作

在正式使用之前,还有一些工作需要完成。扮演角色也是需要授权的,否则任意子账号都可以扮演这些角色会带来不可预计的风险,因此有扮演对应角色需求的子账号需要显式的配置权限。

在授权管理策略中新建自定义的只读授权策略,如下:

创建授权策略1

创建授权策略2

创建授权策略3

  1. {
  2. "Statement": [
  3. {
  4. "Action": "sts:AssumeRole",
  5. "Effect": "Allow",
  6. "Resource": "acs:ram::1776060536409689:role/ramtestreadonly"
  7. }
  8. ],
  9. "Version": "1"
  10. }

按照上文同样的方法,在授权管理策略中新建自定义的上传授权策略,如下:

创建授权策略4

  1. {
  2. "Statement": [
  3. {
  4. "Action": "sts:AssumeRole",
  5. "Effect": "Allow",
  6. "Resource": "acs:ram::1776060536409689:role/ramtestupload"
  7. }
  8. ],
  9. "Version": "1"
  10. }

这里Resource后面填写的内容表示某个角色ID,角色的ID可以在 角色管理 > 角色详情 中找到。创建授权策略5创建授权策略6

  1. 将这两个授权赋给ram_test这个账号。

子用户授权1

子用户授权2

使用STS授权访问

现在一切准备就绪,可以正式使用STS来授权访问了。

这里使用一个简单的STS的JAVA示例。 具体的调用方法如下,更详细的参数解释可以参考 STS API文档

  1. package pop;
  2. import com.aliyuncs.DefaultAcsClient;
  3. import com.aliyuncs.exceptions.ClientException;
  4. import com.aliyuncs.http.MethodType;
  5. import com.aliyuncs.http.ProtocolType;
  6. import com.aliyuncs.profile.DefaultProfile;
  7. import com.aliyuncs.profile.IClientProfile;
  8. import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
  9. import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
  10. import com.aliyuncs.vod.model.v20170314.CreateUploadVideoRequest;
  11. import com.aliyuncs.vod.model.v20170314.CreateUploadVideoResponse;
  12. /**
  13. * Created by liulietao on 2017/7/4.
  14. */
  15. public class TestStsService {
  16. // 目前只有"cn-hangzhou"这个region可用, 不要使用填写其他region的值
  17. public static final String REGION_CN_HANGZHOU = "cn-hangzhou";
  18. // 当前 STS API 版本
  19. public static final String STS_API_VERSION = "2015-04-01";
  20. static AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret,
  21. String roleArn, String roleSessionName, String policy,
  22. ProtocolType protocolType) throws ClientException {
  23. try {
  24. // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
  25. IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
  26. DefaultAcsClient client = new DefaultAcsClient(profile);
  27. // 创建一个 AssumeRoleRequest 并设置请求参数
  28. final AssumeRoleRequest request = new AssumeRoleRequest();
  29. request.setVersion(STS_API_VERSION);
  30. request.setMethod(MethodType.POST);
  31. request.setProtocol(protocolType);
  32. request.setRoleArn(roleArn);
  33. request.setRoleSessionName(roleSessionName);
  34. request.setPolicy(policy);
  35. // 发起请求,并得到response
  36. final AssumeRoleResponse response = client.getAcsResponse(request);
  37. return response;
  38. } catch (ClientException e) {
  39. throw e;
  40. }
  41. }
  42. public static void main(String[] args) {
  43. // 只有 RAM用户(子账号)才能调用 AssumeRole 接口
  44. // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
  45. // 请首先在RAM控制台创建一个RAM用户,并为这个用户创建AccessKeys
  46. String accessKeyId = Env.AK;
  47. String accessKeySecret = Env.AS;
  48. // AssumeRole API 请求参数: RoleArn, RoleSessionName, Policy, and DurationSeconds
  49. // RoleArn 需要在 RAM 控制台上获取
  50. String roleArn = "acs:ram::1776060536409689:role/ramtestupload";
  51. // RoleSessionName 是临时Token的会话名称,自己指定用于标识你的用户,主要用于审计,或者用于区分Token颁发给谁
  52. // 但是注意RoleSessionName的长度和规则,不要有空格,只能有'-' '_' 字母和数字等字符
  53. // 具体规则请参考API文档中的格式要求
  54. String roleSessionName = "RamTestUpload";
  55. // 如何定制你的policy?
  56. String policy = "{\n" +
  57. " \"Version\": \"1\",\n" +
  58. " \"Statement\": [\n" +
  59. " {\n" +
  60. " \"Action\": \"vod:CreateUploadVideo\",\n" +
  61. " \"Resource\": \"*\",\n" +
  62. " \"Effect\": \"Allow\"\n" +
  63. " }\n" +
  64. " ]\n" +
  65. "}";
  66. // 此处必须为 HTTPS
  67. ProtocolType protocolType = ProtocolType.HTTPS;
  68. try {
  69. final AssumeRoleResponse response = assumeRole(accessKeyId, accessKeySecret,
  70. roleArn, roleSessionName, policy, protocolType);
  71. System.out.println("Expiration: " + response.getCredentials().getExpiration());
  72. System.out.println("Access Key Id: " + response.getCredentials().getAccessKeyId());
  73. System.out.println("Access Key Secret: " + response.getCredentials().getAccessKeySecret());
  74. System.out.println("Security Token: " + response.getCredentials().getSecurityToken());
  75. createUploadVideo(response.getCredentials().getAccessKeyId(),
  76. response.getCredentials().getAccessKeySecret(),
  77. response.getCredentials().getSecurityToken());
  78. } catch (ClientException e) {
  79. System.out.println("Failed to get a token.");
  80. System.out.println("Error code: " + e.getErrCode());
  81. System.out.println("Error message: " + e.getErrMsg());
  82. }
  83. }
  84. static void createUploadVideo(String accessKeyId, String accessKeySecret, String token) {
  85. String regionId = Env.REGION;
  86. String endpoint = Env.ENDPOINT;
  87. try {
  88. DefaultProfile.addEndpoint(regionId, regionId, "vod", endpoint);
  89. } catch (ClientException e) {
  90. e.printStackTrace();
  91. }
  92. IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
  93. DefaultAcsClient client = new DefaultAcsClient(profile);
  94. CreateUploadVideoRequest request = new CreateUploadVideoRequest();
  95. request.setSecurityToken(token);
  96. request.setTitle("t1");
  97. request.setFileName("file1.mp4");
  98. request.setFileSize(10240L);
  99. try {
  100. CreateUploadVideoResponse response = client.getAcsResponse(request);
  101. System.out.println("CreateUploadVideoRequest, " + request.getUrl());
  102. System.out.println("CreateUploadVideoRequest, requestId:" + response.getRequestId());
  103. System.out.println("UploadAddress, " + response.getUploadAddress());
  104. System.out.println("UploadAuth, " + response.getUploadAuth());
  105. System.out.println("VideoId, " + response.getVideoId());
  106. } catch (ClientException e) {
  107. System.out.println("action, error:" + e);
  108. e.printStackTrace();
  109. }
  110. }
  111. }
  • RoleArn表示的是需要扮演的角色ID,角色的ID可以在 角色管理 > 角色详情 中找到。
  • RoleSessionName是一个用来标示临时凭证的名称,一般来说建议使用不同的应用程序用户来区分。
  • Policy表示的是在扮演角色的时候额外加上的一个权限限制。
  • DurationSeconds指的是临时凭证的有效期,单位是s,最小为900,最大为3600。
  • id和secret表示的是需要扮演角色的子账号的AccessKey。这里需要解释一下Policy,这里传入的Policy是用来限制扮演角色之后的临时凭证的权限。最后临时凭证获得的权限是角色的权限和这里传入的Policy的交集。

在扮演角色的时候传入Policy的原因是为了灵活性,比如只能现在使用CreateUploadVideo接口。

本文导读目录