阿里云OSS配置私有Bucket生成STS临时授权Url访问

阿里云OSS配置私有Bucket生成STS临时授权Url访问

阿里云提供的 权限管理系统 或 访问控制服务 主要包含两部分,RAM(Resource Access Management)和 STS(Security Token Service),RAM 主要的作用是控制账号系统的权限,你可以使用 RAM 在主账号的权限范围内创建子用户,给不同的子用户分配不同的权限从而达到授权管理的目的。STS 是一个安全凭证(Token)的管理系统,你可以使用 STS 来完成对于临时用户的访问授权。

RAM 和 STS 需要解决的一个核心问题是如何在不暴露主账号的 AccessKey 的情况下安全的授权别人访问,因为一旦主账号的 AccessKey 暴露出去的话会带来极大的安全风险,别人可以随意操作该账号下所有的资源,盗取重要信息等。

RAM 提供一种 长期有效 的权限控制机制,通过分出不同权限的 子账号,将不同的权限分给不同的用户,这样一旦子账号泄露也不会造成全局的信息泄露。但是,由于子账号在一般情况下是长期有效的,因此,子账号的 AccessKey 也是不能泄露的。

相对于 RAM 提供的长效控制机制,STS 提供的是一种 临时访问授权 。通过 STS 可以返回 临时的 AccessKey 和 Token,这些信息可以直接发给临时用户用来访问 OSS 。一般来说,从 STS 获取的权限会受到更加严格的限制,并且拥有时间限制,因此这些信息泄露之后对于系统的影响也很小。

举个例子
当前你的阿里云用户,其在 OSS 下有一个私有的 Bucket,bucket-a 。我们的账户对这个 Bucket 都拥有完全的权限。
为了避免阿里云主账号的 AccessKey 泄露导致安全风险,我们一般会使用 RAM 创建了子账号 如:“testOss”。子账户testOss拥有独立的 AccessKey和AccessKeySecret 。这个时候需要再创建一个新的角色,并且给这个角色赋予Bucket读取的权限。
为了能获取 临时授权,这个时候可以调用 STS 的 AssumeRole 接口,告诉 STS ,子账号 testOss 将要扮演 刚才我们新建的 这个角色,如果成功,STS 会返回一个 临时的 AccessKeyId 、AccessKeySecret 还有 SecurityToken 作为访问凭证。将这个 临时授权凭证 发给需要访问的 临时用户 就可以获得访问 bucket-a的临时权限了,凭证过期的时间可以在调用 AssumeRole 接口的时候指定,最大不超过2小时。
并且将我们临时授权凭使用签名URL进行临时授权,既可以拿到文件访问的临时授权的url。

准备工作

  1. 创建 RAM 子账号
    创建一个 RAM 子账号 oss-test-key,不需要赋予任何权限,因为在扮演角色的时候会自动获得被扮演角色的所有权限。
    注意:这里建议给你创建的子账户赋予上传的权限,否则你在上传的时候需要先获取STS授权才能上传,这里我提前赋予了,所以Bucket是私有的情况下,上传是不受影响的,只是访问预览下载链接会被拒绝
    进入控制台-选择OSS存储对象-选择Access Key
    在这里插入图片描述
    跳转页面,阿里云会告诉你建议使用子账户Access Key-选择开始使用子用户Access Key
    在这里插入图片描述
    创建用户
    在这里插入图片描述
    创建你的账户信息和显示名称(别忘记勾选Open Api调用访问)
    在这里插入图片描述
  2. 创建授权角色
    点击角色-创建角色-选择阿里云账户
    在这里插入图片描述
    配置角色名称-完成-为角色授权
    在这里插入图片描述
    选择系统策略-搜索OSS-选择AliyunOSSReadOnlyAccess(只读访问对象存储服务(OSS)的权限),AliyunOSSFullAccess(管理对象存储服务(OSS)权限),AliyunSTSAssumeRoleAccess(调用STS服务AssumeRole接口的权限)
    在这里插入图片描述
    创建成功后之后,可以在角色列表里面看到你刚才创建的角色信息-点击你刚才创建的角色
    在这里插入图片描述
    记录你的RAM角色名称和ARN信息(一会儿会用到)
    在这里插入图片描述

获取STS临时授权

阿里云OSS官方文档使用STS临时访问凭证SDK:使用STS临时访问凭证访问OSS

public AssumeRoleResponse buildAliyunSTSCredentials() throws ClientException, com.aliyuncs.exceptions.ClientException {
	// STS,这里我以杭州举例,具体你的Bucket地域节点是哪里的就填哪里
    DefaultProfile.addEndpoint("", "", "Sts", "sts.cn-hangzhou.aliyuncs.com");
    //这里需要填充你子账户的accessKeyId与accessKeySecret
    IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
    DefaultAcsClient client = new DefaultAcsClient(profile);
    final AssumeRoleRequest request = new AssumeRoleRequest();
    request.setMethod(MethodType.POST);
    request.setProtocol(ProtocolType.HTTPS);
    //设置临时访问凭证的有效时间为3600秒
    request.setDurationSeconds(60 * 60 * 1L);
    // 要扮演的角色ID-刚才你创建的角色详情里面ARN
    request.setRoleArn("acs:ram::12************41:role/RamTestAppReadOnly"); 
    // 要扮演的角色名称-刚才你创建的角色详情里面角色名称
    request.setRoleSessionName("external-username");
    // request.setPolicy(policy);

    // 生成临时授权凭证
    final AssumeRoleResponse response = client.getAcsResponse(request);
    // 临时凭据AccessKeyId
    String appKey = response.getCredentials().getAccessKeyId();  
    // 临时凭据AccessKeySecret
    String appSecret = response.getCredentials().getAccessKeySecret(); 
    // 临时凭据SecurityToken
    String securityToken = response.getCredentials().getSecurityToken();  
    String expiration = response.getCredentials().getExpiration();
    return response;

accessKeyId表示RAM子账号的AccessKeyId;
accessKeySecret表示RAM子账号的AccessKeySecret;
RoleArn表示的是需要扮演的角色ID,角色的ID可以在 角色管理 > 角色详情 中找到;
RoleSessionName是一个用来标示临时凭证的名称,一般来说建议使用不同的应用程序用户来区分;
DurationSeconds指的是临时凭证的有效期,单位是s,最小为900,最大为3600;
Policy表示的是在扮演角色的时候额外加上的一个权限限制;
appKey表示创建的临时凭据AccessKeyId;
appSecret表示创建的临时凭据AccessKeySecret;
SecurityToken 表示创建的临时凭据SecurityToken;

使用签名URL进行临时授权

阿里云OSS官方文档SDK 使用签名URL进行临时授权

 // 重写的方法以作参考
 public String getAuthorization(AssumeRoleResponse assumeRoleResponse, String fileName) {
        // 创建OSSClient实例。填充你的Endpoint与桶名称
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        //这里替换成你自己的Endpoint和BucketName即可
        String endpoint = properties.getEndpoint();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = properties.getBucketName();
        // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
		// String objectName = fileName;
        if (assumeRoleResponse == null){
            return null;
        }
        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
        String accessKeyId = assumeRoleResponse.getCredentials().getAccessKeyId();
        String accessKeySecret = assumeRoleResponse.getCredentials().getAccessKeySecret();
        // 从STS服务获取的安全令牌(SecurityToken)。
        String securityToken = assumeRoleResponse.getCredentials().getSecurityToken();
        //获取oss client
        OSS ossClient = new OSSClient(properties.getEndpoint(), credentialProvider, configuration);
        // 设置签名URL过期时间为3600秒(1小时)。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        // 生成以GET方法访问的签名URL,访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, fileName, expiration);
        System.out.println(url);
        // 关闭OSSClient。
        ossClient.shutdown();
        return url.toString();

当前返回url就是重新生成带有过期时候的临时授权访问地址
注意:以上方法是将你把你的Bucket设为了私有模式使用,正常公共读与公共读写不需要临时授权访问

总结

其实实现STS临时访问授权的过程就是

  1. 创建RAM子账号
  2. RAM子账号授予STS权限
  3. RAM子账号扮演指定角色
  4. 拿到临时授权凭证
  5. 将授权凭生成签名URL进行临时授权访问
    其中,如果你的子账户没有赋予上传的权限,那么这时候如果你的Bucket又是私有的话,上传是失效的,所以一开始建议将你创建的ARM子账户赋予一个上传的权限。否则你上传的时候也需要先获取STS授权才能上传。
  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值