【问题标题】:Format of private blob storage url, for GET file. Rest API私有 blob 存储 url 的格式,用于 GET 文件。休息 API
【发布时间】:2015-10-06 08:47:52
【问题描述】:

Microsoft 声明获取 Blob 只是普通的 http 获取 https://myaccount.blob.core.windows.net/mycontainer/myblob。但是当我有一个帐户+共享密钥时如何格式化字符串?

我知道有一个 Azure SDK,但我正在为现有的 java ee 系统创建一个“附加组件”,并且无法在 Azure 中运行,所以我使用的是 REST Api。这是我迄今为止尝试过的:

String account = "myaccount";
    String key = "243fedfsdf23f4f";
    String protocol = "http";
    String storageConnectionString = String.format("DefaultEndpointsProtocol=%s;AccountName=%s;AccountKey=%s", protocol, account, key);
    System.out.println(storageConnectionString);        

    URL url = new URL("https://mysite.azureweb.com/myfile.txt");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();

    if (conn.getResponseCode() != 200) {
        throw new IOException(conn.getResponseMessage());
    }

    // Buffer the result into a string
    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = rd.readLine()) != null) {
        sb.append(line);
    }
    rd.close();
    conn.disconnect();

字符串可能需要一些 Base64 编码?

更新

Http 请求看起来像GET https://myAccount.blob.core.windows.net/myDir/myfile.txt HTTP/1.1 x-ms-date: Thu, 01 Oct 2015 12:56:11 GMT x-ms-version: 2015-02-21 Authorization: SharedKey myAccount:asdfkjsladjfsdf827fhwf298f924f92723dfh23f273f2h7h4f Host: myAccount.blob.core.windows.net

我“只是”需要将其打包到一个请求中以获取 /mydir/myfile.txt 中的文件

【问题讨论】:

  • 您可能想删除您在问题中输入的键并更改/删除 azure 服务器上的键值。
  • 私有 blob 存储,所以我需要密钥。这只是一个例子,关键要长得多
  • 好吧,我不知道,只是觉得这是关键,所以想提醒你。
  • 您要使用两个访问密钥之一还是要使用共享访问签名?
  • @PeterKirchner 我已经更新了这个问题。我想使用共享密钥签名

标签: java rest azure


【解决方案1】:

Azure 存储有两种访问类型。一个通过共享密钥,另一个通过共享访问签名

共享密钥提供对整个存储帐户的访问权限。每个存储帐户都有两个共享密钥,它们都是相等的。通常你永远不会泄露你的共享密钥。通常你只在服务器端使用它们,而不是在客户端的应用程序中。

您只想授予某人访问单个文件的权限。因此使用共享密钥是错误的解决方案。

共享访问签名使您可以创建 (REST) 请求,该请求仅限于某些文件或容器。您可以选择写入、读取、删除等权限。您可以定义访问有效的时间范围。对于共享访问签名,您有两种选择:a) ad-hoc 和 b) 基于策略的。临时共享访问签名不能轻易撤销(您可以删除文件或使用于创建共享访问签名的共享密钥无效)。通过删除策略可以轻松撤销基于策略的共享访问签名。

如果您不想使用 Azure SDK,可以创建自己的共享访问签名。 如何构建它们在以下链接中进行了说明:

Constructing a Service SAS

也有样品。

Service SAS Examples

您的文件存储在 BLOB 中。所以你必须使用服务BLOB。在示例页面上,您可以找到以下 BLOB 示例。

signedstart=2013-08-16
signedexpiry=2013-08-17
signedresource=c
signedpermissions=r
signature=dD80ihBh5jfNpymO5Hg1IdiJIEvHcJpCMiCMnN/RnbI=
signedidentifier=YWJjZGVmZw==
signedversion=2013-08-15
responsecontent-disposition=file; attachment
responsecontent-type=binary


StringToSign = r + \n 
               2013-08-16 + \n
               2013-08-17 + \n
               /myaccount/pictures + \n
               YWJjZGVmZw== + \n
               2013-08-15 + \n
               + \n  
               file; attachment + \n
               + \n
               + \n
               binary


HMAC-SHA256(URL.Decode(UTF8.Encode(StringToSign))) = a39+YozJhGp6miujGymjRpN8tsrQfLo9Z3i8IRyIpnQ=

最后,您获得了 REST 请求的 URL。

GET https://myaccount.blob.core.windows.net/pictures/profile.jpg?sv=2013-08-15&st=2013-08-16&se=2013-08-17&sr=c&sp=r&rscd=file;%20attachment&rsct=binary &sig=YWJjZGVmZw%3d%3d&sig=a39%2BYozJhGp6miujGymjRpN8tsrQfLo9Z3i8IRyIpnQ%3d HTTP/1.1

查看这两页的完整说明。

【讨论】:

  • 不错的一个!是的,我有一个共享密钥,可以让我访问整个 blob 存储。那么用base64解码的StringToSign +共享密钥给了我共享访问签名?
  • 最终令牌(参数 'sig')是 base64 编码的。您使用共享密钥对 StringToSign 进行哈希处理。散列函数适用于二进制数据,因此您必须使用 UTF8 对 StringToSign 进行编码(在散列之前)。散列后,您使用 base64 对二进制数据进行编码 --> 这是参数 sig 的值。
【解决方案2】:

有一种简单的方法可以使用 Azure 存储 SDK 生成用于获取私有容器中文件的 SAS。

按照下面的示例代码生成 SAS 密钥并格式化 URL:

String accountName = "<your_account_name>";
String accountKey = "<your_account_key>";
String containerName = "<your_private_container_name>";
String blobFileName = "<your_blob_file_name>";
String storageConnectionString = String.format("DefaultEndpointsProtocol=%s;AccountName=%s;AccountKey=%s", "https", accountName, accountKey);
CloudStorageAccount account = CloudStorageAccount.parse(storageConnectionString);
CloudBlobClient blobClient = account.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference(containerName);
CloudBlockBlob blob = container.getBlockBlobReference(blobFileName);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.setTime(new Date());
policy.setSharedAccessStartTime(calendar.getTime());
calendar.add(Calendar.HOUR, 1);
policy.setSharedAccessExpiryTime(calendar.getTime());
policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ));
String sas = blob.generateSharedAccessSignature(policy, null);
System.out.println(sas)
String urlstr = String.format("https://%s.blob.core.windows.net/%s/%s?%s", accountName, containerName, blobFileName, sas);
System.out.println(urlstr);

详情可以参考文档https://msdn.microsoft.com/en-us/library/hh875756.aspx

【讨论】:

    猜你喜欢
    • 2021-07-08
    • 2018-04-15
    • 1970-01-01
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-26
    相关资源
    最近更新 更多