官方文档:https://help.aliyun.com/document_detail/31920.html
可能我太菜了,官方文档写的很多东西感觉不全,或者不好找,按照下面这些步骤,可能更好理解并实践成功。
一.开通子用户
oss管理控制台
二.设置各种权限
文档:使用STS临时访问凭证访问OSS
开通子用户以后,这个文档了解STS临时访问原理
进入RAM控制台
1.创建RAM用户
访问密钥一定要保存好,只有创建的时候能看到
2.为RAM用户添加STS服务权限
- 单击已创建RAM用户右侧对应的添加权限。
- 在添加权限页面,选择AliyunSTSAssumeRoleAccess权限。
3. 创建用于获取临时访问凭证的角色(用于给RAM用户授权)
角色名自己起,最好有特定含义。保存 ARN
4.为角色授权上传文件的权限
创建上传文件的自定义权限策略
- 在左侧导航栏的权限管理菜单下,单击权限策略管理。
- 单击创建权限策略
- 在新建自定义权限策略页面,填写策略名称为RamTestPolicy[最好与角色名称保存相关,这样意义更明确],配置模式选择脚本配置,并在策略内容中赋予角色向目标存储空间examplebucket【这个是你自己要上传的bucket】下的目录exampledir【这是是你允许这个角色上传数据能保存的文件夹】上传文件的权限。
{"Version": "1","Statement": [{"Effect": "Allow","Action": ["oss:PutObject"],"Resource": ["acs:oss:*:*:examplebucket/exampledir","acs:oss:*:*:examplebucket/exampledir/*"]}]
}
- 点击确定
创建完自定义权限,给角色授予这个自定义的权限
- 在左侧导航栏的身份管理菜单下,单击角色。
- 在角色页面,找到目标RAM角色RamOssTest【你刚创建的角色名】。
- 单击RAM角色RamOssTest右侧的添加权限。
- 在添加权限页面下的自定义策略页签,选择已创建的自定义权限策略RamTestPolicy。
- 单击确定。
注意: 上面这个自定义的策略,只允许了角色 上传文件、其只能上传到examplebucket这个bucket中的exampledir这个文件夹中,后续如果上地址不是这个文件夹就会报权限错误:You have no right to access this object because of bucket acl
也可以配置其他更多的、更精细的权限,文档:RAM Policy常见示例
三、获取临时访问凭证,服务器端接口开发
文档中有他们自己编的比较原生的各种语言的服务端接口,
因为同时做web开发,所有自己写了一个接口,开发框架用了spring boot【其实和SSM一样,只不过配置更简单】
接口代码根据官方文档改的。
服务端接口代码:
@RestController //就是普通的Controller 再加 将响应体以json格式返回 即@ResponseBody
public class OssController {@AutowiredOSS ossClient;//配置文件中取出accessId、sts_endpoint、accessKeySecret、roleArn这些值@Value("${spring.cloud.alicloud.access-key}")private String accessId;@Value("${sts_endpoint}")private String sts_endpoint;@Value("${roleArn}")private String roleArn;@Value("${roleSessionName}")private String roleSessionName;@Value("${spring.cloud.alicloud.secret-key:}")private String accessKeySecret;/*** 获取临时访问凭证* @return*/@RequestMapping("/oss/sts")public R sts(){// 自定义角色会话名称,用来区分不同的令牌,例如可填写为SessionTest。String roleSessionName = "SessionTest";String policy = "{\n" +" \"Version\": \"1\", \n" +" \"Statement\": [\n" +" {\n" +" \"Action\": [\n" +" \"oss:PutObject\"\n" +" ], \n" +" \"Resource\": [\n" +" \"acs:oss:*:*:sleep-monitor/*\" \n" +" ], \n" +" \"Effect\": \"Allow\"\n" +" }\n" +" ]\n" +"}";Map<String, Object> respMap = null;try {// regionId表示RAM的地域ID。以华东1(杭州)地域为例,regionID填写为cn-hangzhou。也可以保留默认值,默认值为空字符串("")。String regionId = "cn-beijing";// 添加endpoint。DefaultProfile.addEndpoint(regionId, "Sts", sts_endpoint);// 构造default profile。IClientProfile profile = DefaultProfile.getProfile(regionId, accessId, accessKeySecret);// 构造client。DefaultAcsClient client = new DefaultAcsClient(profile);final AssumeRoleRequest request = new AssumeRoleRequest();request.setSysMethod(MethodType.POST);request.setRoleArn(roleArn);request.setRoleSessionName(roleSessionName);request.setPolicy(policy); // 如果policy为空,则用户将获得该角色下所有权限。request.setDurationSeconds(3600L); // 设置临时访问凭证的有效时间为3600秒。final AssumeRoleResponse response = client.getAcsResponse(request);respMap = new HashMap<>();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());respMap.put("Expiration",response.getCredentials().getExpiration());respMap.put("AccessKeyId",response.getCredentials().getAccessKeyId());respMap.put("AccessKeySecret",response.getCredentials().getAccessKeySecret());respMap.put("SecurityToken",response.getCredentials().getSecurityToken());respMap.put("RequestId",response.getCredentials().getAccessKeyId());respMap.put("StatusCode",200);return R.ok(respMap);} catch (ClientException e) {System.out.println("Failed:");System.out.println("Error code: " + e.getErrCode());System.out.println("Error message: " + e.getErrMsg());System.out.println("RequestId: " + e.getRequestId());return R.error().put("data",e);}}
}
不管以那种方式写服务端,要求是能正确返回如下的json数据,
包括StatusCode、AccessKeyId、AccessKeySecret、SecurityToken、Expiration
{"StatusCode":200,"AccessKeyId":"STS.3p***dgagdasdg","AccessKeySecret":"rpnwO9***tGdrddgsR2YrTtI","SecurityToken":"CAES+wMIARKAAZhjH0EUOIhJMQBMjRywXq7MQ/cjLYg80Aho1ek0Jm63XMhr9Oc5s˙∂˙∂3qaPer8p1YaX1NTDiCFZWFkvlHf1pQhuxfKBc+mRR9KAbHUefqH+rdjZqjTF7p2m1wJXP8S6k+G2MpHrUe6TYBkJ43GhhTVFMuM3BZajY3VjZWOXBIODRIR1FKZjIiEjMzMzE0MjY0NzM5MTE4NjkxMSoLY2xpZGSSDgSDGAGESGTETqOio6c2RrLWRlbW8vKgoUYWNzOm9zczoqOio6c2RrLWRlbW9KEDExNDg5MzAxMDcyNDY4MThSBTI2ODQyWg9Bc3N1bWVkUm9sZVVzZXJgAGoSMzMzMTQyNjQ3MzkxMTg2OTExcglzZGstZGVtbzI=","Expiration":"2017-12-12T07:49:09Z"
}
运行服务端,并测试,访问你的服务地址,看是否能正确的返回json数据
四、安卓手机上传文件到阿里云OSS
首先需要引入oss依赖:文档
- 可以直接在Android Studio环境中添加:
implementation 'com.aliyun.dpa:oss-android-sdk:2.9.10'
- 也可以引入jar包
将aliyun-oss-sdk-android-2.9.5.jar、okhttp-3.x.x.jar、okio-1.x.x.jar 3个jar包导入libs目录。
jar包百度网盘下载:
链接:https://pan.baidu.com/s/1Odc6kDM2_6rlbjo3s_aepA
提取码:lyg6
【我在build.gradle文件中直接添加依赖的时候,出现了依赖个okhttp jar包冲突, 所以选择了第二种方式】
然后直接上代码:
private void uploadFileTest() {if (HttpUtil.isNetworkAvailable(requireActivity())) {//判断是否有网络String endpoint = "oss-cn-beijing.aliyuncs.com";String buckName = "sleep-monitor";String stsServer = RequestCallback.baseAddress + "api/thirdparty/oss/sts";//请求sts的地址// 推荐使用OSSAuthCredentialsProvider。token过期可以及时更新。OSSCredentialProvider credentialProvider = new OSSAuthCredentialsProvider(stsServer);
// //配置类如果不设置,会有默认配置。
// ClientConfiguration conf = new ClientConfiguration();
// conf.setConnectionTimeout(15 * 1000); // 连接超时,默认15秒。
// conf.setSocketTimeout(15 * 1000); // socket超时,默认15秒。
// conf.setMaxConcurrentRequest(5); // 最大并发请求数,默认5个。
// conf.setMaxErrorRetry(2); // 失败后最大重试次数,默认2次。OSS oss = new OSSClient(MyApplication.getAppContext(), endpoint, credentialProvider);File[] files = MyApplication.getAppContext().getExternalFilesDirs(null);//获取该应用文件下的内部存储位置File file = new File(files[0],"20211013脑电丢包测试20211013191115.csv");//要上传的文件//第二个变量是上传的文件夹,这个文件夹必须是之前自定义权限中写的那个文件夹PutObjectRequest put = new PutObjectRequest(buckName, "睡眠APP/APP测试.txt", String.valueOf(file));try {Log.d(TAG,"开始上传...");PutObjectResult putResult = oss.putObject(put);Log.d(TAG,"PutObject: UploadSuccess");Log.d(TAG,"ETag:" + putResult.getETag());Log.d(TAG,"RequestId:" + putResult.getRequestId());} catch (ClientException e) {// 客户端异常,例如网络异常等。Log.e(TAG,"客户端异常:" + e);e.printStackTrace();} catch (ServiceException e) {// 服务端异常。Log.e(TAG,"RequestId:" + e.getRequestId());Log.e(TAG,"ErrorCode:"+ e.getErrorCode());Log.e(TAG,"HostId:"+ e.getHostId());Log.e(TAG,"RawMessage:"+ e.getRawMessage());}} else {ToastUtil.showShortToast(MyApplication.getAppContext().getResources().getString(R.string.network_enable));}}
还有异步上传可以看阿里云文档-简单上传
本文链接:https://my.lmcjl.com/post/2335.html
4 评论