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

9
我知道有一个库可以使用Azure Storage上传文件。我参考了这个,但他们没有提供如何使用SAS的信息。我有账户名称和用于访问和上传文件的SAS URL。但我不知道如何使用它来上传文件。如果我使用上述库,它会显示无效的存储连接字符串,因为我没有在其中传递密钥(使用SAS不需要密钥)。所以我很困惑如何上传文件。我还查阅了这篇文档,想要使用SAS上传文件。但是,我没有找到正确的步骤。他们为其Windows应用程序制作了演示文稿,我希望能在Android上使用SAS实现相同的功能。
更新:参考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();
    }

现在,当我仅上传文本时,它会显示以下错误:

服务器无法验证请求。确保Authorization标头的值正确形成,包括签名。

现在,我的要求是上传图像文件。因此,当我取消上传图像文件的代码注释时,它不会给我任何错误,但也不会上传图像文件。


请在您的问题中确认SAS。 - subhash singh
@subhashsingh 你在我的问题中说的“confirm sas”是什么意思?我不明白你在说什么。 - Shreyash Mahajan
@subhashsingh,您能回答我的问题吗?我不理解您的评论的意思。 - Shreyash Mahajan
1
我认为AzureMobileStorage不是Azure中的任何术语。您的意思是使用Azure移动服务(通过SAS)将文件存储在Azure存储中吗? - subhash singh
1
@iDroidExplorer,你有几个问题与SAS无关。为什么在你创建的URL中需要toString?你的SAS令牌是URL还是仅令牌?为什么要从Blob URI创建容器?你能澄清一下这些吗? - Emily Gerner
显示剩余4条评论
2个回答

3

@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

现在,您需要将SAS URL与您的上传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存储上传文件。如果您有任何疑问,请告诉我,我可以帮忙解决。


请帮我解决这个问题。如何使用单个类对多个表进行序列化? - kumar kundan

0

上传图片到BLOB存储。我花了几个小时才找到它。看一下:

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

首先,您拍照并插入一个包含 Azure 存储使用的新元数据字段的 TodoItem 行到 SQL 数据库中。 一个新的移动服务 SQL 插入脚本向 Azure 存储请求一个共享访问签名(SAS)。 该脚本将 SAS 和 blob 的 URI 返回给客户端。 客户端使用 SAS 和 blob URI 上传照片。

那么什么是SAS

在客户端应用程序中存储上传数据到 Azure 存储服务所需的凭据是不安全的。相反,您将这些凭据存储在移动服务中,并使用它们生成授予上传新图像权限的共享访问签名(SAS)。这个带有5分钟过期时间的凭证会被移动服务安全地返回给客户端应用程序。然后,应用程序使用这个临时凭证来上传图像。

如需进一步查询和详细分析,请访问官方文档 https://azure.microsoft.com/zh-cn/documentation/articles/mobile-services-android-upload-data-blob-storage/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接