使用 SAS(共享访问签名)通过 Azure 存储上传文件

Upload file with Azure Storage using SAS (Shared Access Signature)

我知道有一个库可用于使用 Azure 存储上传文件。我已经参考 this 了。

但是,他们没有提供有关如何使用 SAS 的信息。我有帐户名和 sas url 用于访问和上传文件。但是我不知道怎么用它来上传文件。

如果我使用上面提到的库,它会显示无效的存储连接字符串,因为我没有在其中传递密钥(sas 不需要)。所以我很困惑如何上传文件。

关于使用 sas 上传文件,我也参考了 this 文档。但没有采取适当的步骤来做到这一点。他们已经为他们的 windows 应用程序制作了演示。我想在 android 中使用 sas。

更新

我已尝试参考 console app made by Azure 使用以下代码来检查和访问 SAS。

 try {
        //Try performing container operations with the SAS provided.

        //Return a reference to the container using the SAS URI.
        //CloudBlockBlob blob = new CloudBlockBlob(new StorageUri(new URI(sas)));
        String[] str = userId.split(":");
        String blobUri = "https://myStorageAccountName.blob.core.windows.net/image/" + str[1] + "/story/" + storyId + "/image1.jpg" + sas.toString().replaceAll("\"","");
        Log.d(TAG,"Result:: blobUrl 1 : "+blobUri);
        CloudBlobContainer container = new CloudBlobContainer(new URI(blobUri));
        Log.d(TAG,"Result:: blobUrl 2 : "+blobUri);
        CloudBlockBlob blob = container.getBlockBlobReference("image1.jpg");
        String filePath = postData.get(0).getUrl().toString();
        /*File source = new File(getRealPathFromURI(getApplicationContext(),Uri.parse(filePath))); // File path
        blob.upload(new FileInputStream(source), source.length());*/
        Log.d(TAG,"Result:: blobUrl 3 : "+blobUri);
        //blob.upload(new FileInputStream(source), source.length());
        //blob.uploadText("Hello this is testing..."); // Upload text file
        Log.d(TAG, "Result:: blobUrl 4 : " + blobUri);
        Log.d(TAG, "Write operation succeeded for SAS " + sas);
        response = "success";
        //Console.WriteLine();
    } catch (StorageException e) {
        Log.d(TAG, "Write operation failed for SAS " + sas);
        Log.d(TAG, "Additional error information: " + e.getMessage());
        response = e.getMessage();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        response = e.getMessage();
    } catch (IOException e) {
        e.printStackTrace();
        response = e.getMessage();
    } catch (URISyntaxException e) {
        e.printStackTrace();
        response = e.getMessage();
    } catch (Exception e){
        e.printStackTrace();
        response = e.getMessage();
    }

现在,当我只上传文本时,它说我低于错误

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

现在,我的要求是上传图片文件。所以当我取消注释上传图像文件的代码时,它没有给我任何错误,但甚至没有上传图像文件。

正在将图片上传到 BLOB 存储。搜索了几个小时后我得到了它。看看:-

上传照片图像是一个多步骤过程:

首先拍摄一张照片,然后将 TodoItem 行插入 SQL 数据库,其中包含 Azure 存储使用的新元数据字段。 新的移动服务 SQL 插入脚本向 Azure 存储请求 Shared Access Signature (SAS)。 该脚本 returns SAS 和 blob 到客户端的 URI。 客户端使用 SAS 和 blob URI 上传照片。

那么什么是SAS

将上传数据到客户端应用程序中的 Azure 存储服务所需的凭据存储起来是不安全的。相反,您将这些凭据存储在您的移动服务中,并使用它们生成一个 Shared Access Signature (SAS) 以授予上传新图像的权限。 SAS,一个有效期为 5 分钟的凭据,由移动服务安全地返回给客户端应用程序。该应用程序然后使用此临时凭据上传图像。

进一步查询和详细分析。访问此官方文档 https://azure.microsoft.com/en-us/documentation/articles/mobile-services-android-upload-data-blob-storage/

@kumar kundal 您所解释的机制是完全正确的。 下面是关于将个人资料图像上传到 Azure 服务器的更详细的答案。

首先创建 SAS url 以将图像(或任何文件)上传到 blob 存储:

String sasUrl = "";
// mClient is the MobileServiceClient
ListenableFuture<JsonElement> result = mClient.invokeApi(SOME_URL_CREATED_TO_MAKE_SAS, null, "GET", null);
Futures.addCallback(result, new FutureCallback<JsonElement>() {
        @Override
        public void onSuccess(JsonElement result) {
            // here you will get SAS url from server
            sasUrl = result; // You need to parse it as per your response
        }

        @Override
        public void onFailure(Throwable t) {
        }
    });

现在,您有了 sasURL。这将类似于以下字符串:

sv=2015-04-05&ss=bf&srt=s&st=2015-04-29T22%3A18%3A26Z&se=2015-04-30T02%3A23%3A26Z&sr=b&sp=rw&sip=168.1.5.60-168.1.5.70&spr=https&sig=F%6GRVAZ5Cdj2Pw4tgU7IlSTkWgn7bUkkAg8P6HESXwmf%4B

现在,您需要在上传 url 时附加 sas url。请参阅下面的代码,其中我在上传请求中附加了 SAS url。

try {
        File source = new File(filePath); // File path
        String extantion = source.getAbsolutePath().substring(source.getAbsolutePath().lastIndexOf("."));
        // create unique number to identify the image/file.
        // you can also specify some name to image/file
        String uniqueID = "image_"+ UUID.randomUUID().toString().replace("-", "")+extantion; 
        String blobUri = MY_URL_TO_UPLOAD_PROFILE_IMAGE + sas.replaceAll("\"","");
        StorageUri storage = new StorageUri(URI.create(blobUri));
        CloudBlobClient blobCLient = new CloudBlobClient(storage);
        CloudBlobContainer container = blobCLient.getContainerReference("");
        CloudBlockBlob blob = container.getBlockBlobReference(uniqueID);
        BlobOutputStream blobOutputStream = blob.openOutputStream();
        byte[] buffer = fileToByteConverter(source);
        ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer);
        int next = inputStream.read();
        while (next != -1) {
            blobOutputStream.write(next);
            next = inputStream.read();
        }
        blobOutputStream.close();
        // YOUR IMAGE/FILE GET UPLOADED HERE
        // IF YOU HAVE FOLLOW DOCUMENT, YOU WILL RECEIVE IMAGE/FILE URL HERE 
    } catch (StorageException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e){
        e.printStackTrace();
    }

希望这些信息对您使用 blob 存储上传文件有所帮助。 如果您对此有任何疑问,请告诉我。我可以提供帮助。