使用STS临时访问凭证访问OSS

说明

在使用阿里云的oss 获取临时访问凭证的时候,报错信息bucket 不存在,后来找阿里云的售后,他说用他给我的代码,我一看这个代码没有使用到policy,那岂不是自定义权限策略没用,但是却不报错了,可以正常上传了,一下是具体流程,有老铁知道的,欢迎留言。

前提条件

已确保当前账号为阿里云账号或者被授予AliyunRAMFullAccess权限的RAM用户。

适用场景

使用STS授权用户直接访问OSS的流程如下:App用户登录。App用户和云账号无关,它是App的终端用户,App服务器支持App用户登录。对于每个有效的App用户来说,需要App服务器能定义出每个App用户的最小访问权限。

  1. App服务器请求STS服务获取一个安全令牌(SecurityToken)。在调用STS之前,App服务器需要确定App用户的最小访问权限(用RAM Policy来自定义授权策略)以及凭证的过期时间。然后通过扮演角色(AssumeRole)来获取一个代表角色身份的安全令牌(SecurityToken)。
  2. STS返回给App服务器一个临时访问凭证,包括一个安全令牌(SecurityToken)、临时访问密钥(AccessKeyId和AccessKeySecret)以及过期时间。
  3. App服务器将临时访问凭证返回给App客户端,App客户端可以缓存这个凭证。当凭证失效时,App客户端需要向App服务器申请新的临时访问凭证。例如,临时访问凭证有效期为1小时,那么App客户端可以每30分钟向App服务器请求更新临时访问凭证。
  4. App客户端使用本地缓存的临时访问凭证去请求OSS API。OSS收到访问请求后,会通过STS服务来验证访问凭证,正确响应用户请求。

具体配置流程这里就不多说了,不懂的可以去看阿里云的帮助文档,这里重点说一下,怎么获取访问凭证,

步骤1:获取临时访问凭证

以下Java代码用于获取临时访问凭证:

package cn.ityoudream.cn.stsjava;

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 java.util.HashMap;
import java.util.Map;

public class STS {
    public static void main(String[] args) throws ClientException {
        String AccessKeyId = "";
        String accessKeySecret = "";
        // 填写步骤3获取的角色ARN。
        String roleArn = "acs:ram::1551714601834638:role/sts";
        // 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。
        String roleSessionName = "sts";

        Map<String,Object> maps = new HashMap<>();

        String policy = "{\n" +
                "    \"Version\": \"1\",\n" +
                "    \"Statement\": [\n" +
                "     {\n" +
                "           \"Effect\": \"Allow\",\n" +
                "           \"Action\": [\n" +
                "             \"oss:PutObject\"\n" +
                "           ],\n" +
                "           \"Resource\": [\n" +
                "             \"acs:oss:*:*:bucket\",\n" +
                "             \"acs:oss:*:*:ilian/*\"\n" +
                "           ]\n" +
                "     }\n" +
                "    ]\n" +
                "}";

        maps.put("policy", policy);

        try {
            initSTS(AccessKeyId, accessKeySecret, roleArn, roleSessionName, policy);
        } catch (ClientException e) {
            //可以捕获下异常,比如这个地方超时了,可以使用for 循环
            for(int retry = 0; retry <= 10; retry ++) {
                initSTS(AccessKeyId, accessKeySecret, roleArn, roleSessionName, policy);
            }
        }
    }

    private static void initSTS(String accessKeyId, String accessKeySecret, String roleArn, String roleSessionName, String policy) throws ClientException {
        String regionId = "cn-hangzhou";
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
        DefaultAcsClient client = new DefaultAcsClient(profile);
        final AssumeRoleRequest request = new AssumeRoleRequest();
        request.setConnectTimeout(100000);
        request.setMethod(MethodType.POST);
        request.setRoleArn(roleArn);
        request.setRoleSessionName(roleSessionName);
//        request.setPolicy(policy); // 如果policy为空,则用户将获得该角色下所有权限。
        request.setDurationSeconds(3600L); // 设置临时访问凭证的有效时间为3600秒。
        final AssumeRoleResponse response = client.getAcsResponse(request);
        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(response.getCredentials().getExpiration());
        System.out.println("RequestId: " + response.getRequestId());
    }

}
 

这段代码我说明一下,刚开始我用的官网的代码,获取临时访问凭证,提示bucket不存在,然后阿里云的售后给的这段代码,我仔细看了一下,没有使用policy,那是不是不用配置这个也可以用了?这点有点疑惑,不过最后确定是可以获取临时凭证的。就没有想的太多,能用就行

步骤2:使用临时访问凭证上传文件至OSS

以Java SDK 3.12.0版本为例,将本地D:\\localpath路径下的exampletest.txt文件上传至存储空间examplebucket下的exampledir目录的示例代码如下:其中的accessKeyId和accessKeySecret是第五步获取的

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.PutObjectRequest;

import java.io.File;

public class Upload {
    public static void main(String[] args) {
// Endpoint以杭州为例,其它Region请按实际情况填写。
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// 填写步骤五获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
String accessKeyId = "<yourAccessKeyId>";
String accessKeySecret = "<yourAccessKeySecret>";
// 填写步骤五获取的安全令牌SecurityToken。
String securityToken = "<yourSecurityToken>";

// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
// 将本地文件exampletest.txt上传至目标存储空间examplebucket下的目录exampledir。
PutObjectRequest putObjectRequest = new PutObjectRequest("examplebucket", "exampledir/exampletest.txt", new File("D:\\localpath\\exampletest.txt"));

// 如果需要上传时设置存储类型与访问权限,请参考以下示例代码。
// ObjectMetadata metadata = new ObjectMetadata();
// metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
// metadata.setObjectAcl(CannedAccessControlList.Private);
// putObjectRequest.setMetadata(metadata);

// 上传文件。
ossClient.putObject(putObjectRequest);

// 关闭OSSClient。
ossClient.shutdown();
   }
}                    
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃菜的小虾米

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值