如何使用SAS令牌从C#连接到Azure BlobStorage? [英] How to use SAS Token to connect to Azure BlobStorage from C#?

查看:6
本文介绍了如何使用SAS令牌从C#连接到Azure BlobStorage?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl;dr:我正在尝试使用SAS从C#连接到Azure BlobStorage,但似乎无法通过StorageException说明服务器无法对请求进行身份验证。我怀疑我的连接字符串有问题。


我正在使用库Microsoft.Azure.Storage.Blob11.2.3.0和Microsoft.Azure.Storage.Common11.2.3.0从.NET Core 3.1应用程序连接到Azure BlobStorage。

建立此连接的C#代码如下:

var storageAccount = CloudStorageAccount.Parse(connectionString);
var blobClient = storageAccount.CreateCloudBlobClient();

当使用包含AccountNameAccountKeyEndpointSuffixDefaultEndpointsProtocol(这是https)1字段的连接字符串时,它可以完美地工作。(我可以连接并执行枚举容器和BLOB之类的操作,还可以创建容器和BLOB并上传数据。)


现在,我应该使用SAS连接到相同的BlobStorage。为此,我得到了以下几点信息(这里匿名给某种占位符,因为我将在下面引用它们):

  • <StorageAccount>(与上述连接字符串中AccountName字段的值相同)
  • <Container>
  • <Blob-SAS-Token>
  • <Blob-SAS-URL>(这实际上是由这里找到的其他信息组成的,即<DefaultEndpointsProtocol>://<StorageAccount>.blob.<EndpointSuffix>/<Container>?<Blob-SAS-Token>)

我可以使用上述<Blob-SAS-URL>Microsoft Azure Storage Explorer成功建立到所述BlobStorage容器的连接。2

但是,到目前为止,我还无法从C#代码成功使用SAS。

我尝试了多种方式来编写连接字符串,例如:

  • BlobEndpoint=<DefaultEndpointsProtocol>://<StorageAccount>.blob.<EndpointSuffix>;SharedAccessSignature=<Blob-SAS-Token>
  • BlobEndpoint=<DefaultEndpointsProtocol>://<StorageAccount>.blob.<EndpointSuffix>/<Container>;SharedAccessSignature=<Blob-SAS-Token>

根据docs,此起作用。其中,概述了一个基于SAS的连接字符串,它最多包含五个字段-BlobEndpointQueueEndpointTableEndpointFileEndpointSharedAccessSignature,其中在SAS旁边必须指定四个端点之一。

我还尝试以不同于使用(可能格式错误的)连接字符串的方式创建/填充CloudStorageAccount实例,例如:

var storageAccount = new CloudStorageAccount(
    new StorageCredentials("<Blob-SAS-Token>"),
    "<StorageAccount>", "<EndpointSuffix>", true);

遗憾的是,无论我如何尝试,只要我尝试以这种方式从BlobStorage检索任何数据,就会抛出一个Microsoft.Azure.Storage.StorageException,声明

服务器无法对请求进行身份验证。请确保包括签名在内的授权标头的值格式正确。

我本地计算机上的UTC时间与我可以在在线资源上找到的当前UTC时间完全一致。因为我可以从同一台计算机上的另一个应用程序连接到我的SAS信息,所以这个问题很可能与环境的任何方面无关(例如,我的IP地址在某个阻止列表或类似列表中丢失了条目)。相反,我怀疑我没有提供建立连接所需的足够信息。

要使此连接正常工作,我必须更改什么?


1:为了不泄露任何机密信息,我将使用某种占位符和凭据来写这篇文章。我希望这不会太令人困惑。另一方面,它实际上应该允许通过几个查找和替换操作轻松地使信息适应可用的任何样本端点。

2:为此,我右键单击存储帐户树节点,然后连接到Azure存储...&>Blob容器&SAS URL(共享访问签名

推荐答案

基于连接字符串的解决方案如下。

基于Swetha's comment,我能够使用以下代码进行连接:

var creds = new StorageCredentials("<Blob-SAS-Token>");
var blobContainer = new CloudBlobContainer(new Uri("<DefaultEndpointsProtocol>://<StorageAccount>.blob.<EndpointSuffix>/<Container>"), creds);

然后我可以从blobContainer检索数据并将数据上载到blobContainer

不幸的是,这意味着用于连接到BlobStorage的代码看起来不同于连接字符串。因此,我将需要提供、测试和维护两个不同的代码路径,具体取决于所提供的连接配置的类型(并且不能保证第三种身份验证方法不需要另一个代码路径--我现在已经asked about in a separate question)。


更新:基于an answer to my question about storing connection data,我现在了解到实际上可以使用连接字符串与SA连接。以下格式已被证明有效:

  • BlobEndpoint=<DefaultEndpointsProtocol>://<StorageAccount>.blob.<EndpointSuffix>;SharedAccessSignature=<Blob-SAS-Token>
  • DefaultEndpointsProtocol=<DefaultEndpointsProtocol>;EndpointsSuffix=<EndpointsSuffix>;SharedAccessSignature=<Blob-SAS-Token>

然后,重要的一点是(至少如果SA是特定于容器的--我不确定是否总是这样),我可以在容器中工作,但不能在容器(或容器外的任何东西)上工作。即:

  • 虽然我可以通过将容器名称传递给GetContainerReference来检索CloudBlobContainer实例,但我不能调用ListContainers(这会引发异常,而不是仅枚举我可以使用SA访问的容器集)。
  • 我必须假定容器已经存在。Exists()CreateIfNotExists()在容器上调用时都会引发异常。1

一旦遵守这些限制,就可以再次使用CloudStorageAccount.Parse(connectionString)


1:我已创建了一个separate question about how to safely check for a container's existence

这篇关于如何使用SAS令牌从C#连接到Azure BlobStorage?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆