在互联网中,使用OBS作为存储在Web应用、移动APP(手机Android、iOS应用)中获得了越来越广泛的应用。Android和iOS应用使用OBS服务时,不能直接存储访问密钥(AK/SK),这样可能会导致访问密钥(AK/SK)被黑客软件破解获取,进而可能导致存放在云存储中的文件数据被窃取,甚至被篡改。为了更好地保护应用数据,避免被攻击后数据泄露以及越权访问的风险,推荐使用预签名URL方式访问OBS。
应用客户端每个请求都将向应用服务器申请预签名URL,该预签名URL有效期由应用服务器管理。具体流程如图1。
角色分析如下:
Android和iOS应用使用OBS服务时,不需要存储访问密钥(AK/SK)。应用在上传前必须向用户的应用服务器申请访问OBS的URL,并携带必须信息,包括请求类型、资源路径和资源名称。比如上传操作需要标识该URL为上传请求,需要包含上传的路径以及上传对象的名称;下载操作需要标识该URL为下载请求,需要包含所下载对象的名称。
https://examplebucket.obs.cn-north-4.myhuaweicloud.com/objectkey?AccessKeyId=AccessKeyID&Expires=1532779451&Signature=0Akylf43Bm3mD1bh2rM3dmVp1Bo%3D
URL中会包含用户的AK、签名、有效期、资源等信息,任何拿到这个URL的人均可执行这个操作。OBS服务收到这个请求并验证签名后,认为该请求就是签发URL的用户自己在执行操作。例如构造一个携带签名信息的下载对象URL,拿到相应URL的人能下载这个对象,但该URL只在Expires指定的失效时间内有效(如果使用临时访问密钥,有效期为临时访问密钥有效时长和Expires的最小值)。URL中携带签名主要用于在不提供给其他人SK的情况下,让其他人能用预签发的URL来进行身份认证,并执行预定义的操作。
预签名URL需要通过访问密钥生成,请参考访问密钥(AK/SK)获取。其中访问密钥(AK/SK)对应的用户需设置所需的最小权限,具体权限设置方法参考向IAM用户授予OBS资源权限。
详细信息请参考URL中携带签名。
请在各语言的SDK开发指南中获取。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | // 本次请求的桶的endpoint
String endPoint = "http://your-endpoint";
// 替换为您的AK、SK
String ak = "*** Provide your Access Key ***";
String sk = "*** Provide your Secret Key ***";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
// 替换您的过期时间,单位是秒
long expireSeconds = 3600L;
// 替换成您对应的操作
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.PUT, expireSeconds);
// 替换为请求本次操作访问的桶名和对象名
request.setBucketName("bucketname");
request.setObjectKey("objectname");
TemporarySignatureResponse response = obsClient.createTemporarySignature(request);
// 成功返回预签名URL,如下打印URL信息
System.out.println(response.getSignedUrl());
|
更多相关介绍和示例代码,请参见使用URL进行授权访问。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | public class Demo extends Activity
{
private static String bucketName = "my-obs-bucket-demo";
private static String objectKey = "my-obs-object-key-demo";
private static OkHttpClient httpClient;
private static StringBuffer sb;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb = new StringBuffer();
/*
* Constructs a client instance with your account for accessing OBS
*/
httpClient = new OkHttpClient.Builder().followRedirects(false).retryOnConnectionFailure(false)
.cache(null).build();
final TextView tv = (TextView)findViewById(R.id.tv);
tv.setText("Click to start test");
tv.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
tv.setClickable(false);
AsyncTask<Void, Void, String> task = new DownloadTask();
task.execute();
}
});
}
class DownloadTask extends AsyncTask<Void, Void, String>
{
@Override
protected String doInBackground(Void... params)
{
try
{
/*
* 这里需要您自己构造上传对象请求到应用服务器来生成到OBS请求的预签名URL
* 假如响应结果存放在:response,通过方法获取getSignedUrl()
*/
sb.append("Uploading a new object to OBS from a file\n\n");
Request.Builder builder = new Request.Builder();
// 使用PUT请求上传对象
Request httpRequest = builder.url(response.getSignedUrl()).put(RequestBody.create(MediaType.parse(contentType), "Hello OBS".getBytes("UTF-8"))).build();
Call c = httpClient.newCall(httpRequest);
Response res = c.execute();
sb.append("\tStatus:" + res.code());
if (res.body() != null) {
sb.append("\tContent:" + res.body().string() + "\n");
}
res.close();
/*
* 这里需要您自己构造下载对象请求到应用服务器来生成到OBS请求的预签名URL
* 假如响应结果存放在:response,通过方法获取getSignedUrl()
*/
sb.append("Downloading an object\n\n");
Request.Builder builder = new Request.Builder();
// 使用GET请求下载对象
Request httpRequest = builder.url(response.getSignedUrl()).get().build();
OkHttpClient httpClient = new OkHttpClient.Builder().followRedirects(false).retryOnConnectionFailure(false).cache(null).build();
Call c = httpClient.newCall(httpRequest);
Response res = c.execute();
System.out.println("\tStatus:" + res.code());
if (res.body() != null) {
sb.append("\tContent:" + res.body().string() + "\n");
}
res.close();
return sb.toString();
}
catch (Exception e)
{
sb.append("\n\n");
sb.append(e.getMessage());
return sb.toString();
}
finally
{
if (httpClient != null)
{
try
{
/*
* Close obs client
*/
httpClient.close();
}
catch (IOException e)
{
}
}
}
}
@Override
protected void onPostExecute(String result)
{
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText(result);
tv.setOnClickListener(null);
tv.setMovementMethod(ScrollingMovementMethod.getInstance());
}
}
}
|
在 Jupyter 里使用 Python 来分析日历,以了解你是如何使用时间的。 Python 在探...
来源 | 阿里云基础设施微信公众号 ODCC2020 ODCC2020峰会,方升开源项目斩获优秀...
云服务器的降临,加速了云计算时代的来临。传统物理服务器的冷却,加之云服务器...
云计算技术的进步带来供应链管理的重大改进。现代云计算软件提供了广泛的解决方...
VPS简单说就是虚拟机,已经存在多年,很多用户对其都比较了解。目前,大热全球的...
本文转载自微信公众号「大迁世界」,可以通过以下二维码关注。转载本文请联系大...
对于vlookup函数,很多人都有会这样的想法:vlookup函数的第三参数为什么就不能...
高硬防 服务器租用 网站被攻击了怎么办?游戏被攻击了怎么办?其实一般常见的攻...
BigDecimal bigDecimal4 = new BigDecimal("1");BigDecimal bigDecimal5 = new B...
解析 域名 需要多少钱?如果是在 TOP云 设置域名解析,是不需要收费的。TOP云默...