0

您好,我在 Microsoft Azure 云存储上遇到 Cors 错误。

我正在按如下方式生成我的 SAS:

public SAS(string containername, string id, SharedAccessBlobPermissions permissions)
{
    this.id = id;
    CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
    CloudBlobContainer containerReference = cloudStorageAccount.CreateCloudBlobClient().GetContainerReference("teeessssttt");
    if (containerReference.CreateIfNotExists(null, null))
    {
        BlobConfig.configureCORS();
    }
    CloudBlockBlob blockBlobReference = containerReference.GetBlockBlobReference(id);
    SharedAccessBlobPolicy sharedAccessBlobPolicy = new SharedAccessBlobPolicy()
    {
        Permissions = permissions
    };
    DateTime utcNow = DateTime.UtcNow;
    sharedAccessBlobPolicy.SharedAccessStartTime = new DateTimeOffset?(utcNow.AddMinutes(-5));
    DateTime dateTime = DateTime.UtcNow;
    sharedAccessBlobPolicy.SharedAccessExpiryTime = new DateTimeOffset?(dateTime.AddMinutes(15));
    string sharedAccessSignature = blockBlobReference.GetSharedAccessSignature(sharedAccessBlobPolicy);
    this.HostingSite = blockBlobReference.Uri.AbsoluteUri;
    this.Token = sharedAccessSignature;
    this.fullurl = string.Concat(this.HostingSite, this.Token);
}

这会产生类似的东西:

{"fullurl":"https://ingenovatebeta.blob.core.windows.net/teeessssttt/7554eb72-f361-4715-a255-a5d6922706b0?sv=2013-08-15&sr=b&sig=iVL4zeytgC1H7W09lV2YZspOKlzF433oqsx9I6cfI68%3D&st=2014-10-24T05%3A58%3A13Z&se=2014-10-24T06%3A18%3A13Z&sp=w","HostingSite":"https://ingenovatebeta.blob.core.windows.net/teeessssttt/7554eb72-f361-4715-a255-a5d6922706b0","id":"7554eb72-f361-4715-a255-a5d6922706b0","Token":"?sv=2013-08-15&sr=b&sig=iVL4zeytgC1H7W09lV2YZspOKlzF433oqsx9I6cfI68%3D&st=2014-10-24T05%3A58%3A13Z&se=2014-10-24T06%3A18%3A13Z&sp=w"}

我正在按如下方式设置我的cors:

CorsRule corsRule = new CorsRule();
corsRule.AllowedOrigins.Add("https://---------------.com");
corsRule.AllowedMethods = CorsHttpMethods.Get | CorsHttpMethods.Post | CorsHttpMethods.Put |           
CorsHttpMethods.Options;
corsRule.AllowedHeaders.Add("*");
corsRule.ExposedHeaders.Add("*");
corsRule.MaxAgeInSeconds = (int)TimeSpan.FromDays(5).TotalSeconds;
corsRules.Add(corsRule);
serviceProperty.Cors = corsProperty;

当我仅将文件上传到 GUID 时,这很有效。例如,将我的上传 URI 设置如下:

$.get("/api/sas", (function (json) {    
    var baseUrl = json.fullurl;                                  
    myDropzone.options.url = baseUrl;
    myDropzone.processFile(file);
}));

然而,我的所有文件最终都作为 GUID 存储在我的云存储中,没有文件名或扩展名,这使得检索图像等变得困难。在显示的示例中,您可以添加文件名。我遵循了以下示例:

$.get("/api/sas", (function (json) {

    var baseUrl = json.fullurl;
    var indexOfQueryStart = baseUrl.indexOf("?");
    submitUri = baseUrl.substring(0, indexOfQueryStart) + '/' + file.name + baseUrl.substring(indexOfQueryStart);

    myDropzone.options.url = submitUri;
    myDropzone.processFile(file);
 }));

但是它不起作用。此时我收到一个 CORS 错误:

XMLHttpRequest cannot load https://myurl/mycontainer/82b7f14b-ee7c-45a3…2B%2BmtAJw%3D&st=2014-10-23T04%3A34%3A22Z&se=2014-10-23T04%3A54%3A22Z&sp=w. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://stagingrapidrealities.azurewebsites.net' is therefore not allowed access. The response had HTTP status code 403. ​
4

1 回答 1

2

我想我知道发生了什么。基本上你的 CORS 设置没有问题。他们非常好。问题出在您的 SAS 上。

正在发生的事情是您正在 blob 上创建 SAS(blob 的名称是7554eb72-f361-4715-a255-a5d6922706b0)。这意味着计算的签名包含此 blob 名称。然后,当您上传文件时,您将通过将文件名 ( clown.jpg) 附加到 URL 来更改 blob 名称。这实质上使 SAS 签名无效,因此您收到 403 错误。

有两种方法可以解决此问题:

  1. 根据您上传的实际文件计算 blob 上的 SAS:在这种情况下,当用户在您的应用程序中选择一个文件时,您将 blob 名称传递给您的服务器并让它返回该文件的 SAS URL,然后您就用那个。这就是您的代码在使用 GUID 上传文件时工作的原因。
  2. 在容器上计算 SAS :不是在 blob 上计算 SAS,而是在容器上而不是 blob 上计算。过程保持不变。您会注意到的区别在于 SAS URL 中的src意思是容器)而不是b(意思是 blob)。然后你会使用相同的方法来推导submitUrl(即找到索引?并在那里插入文件名)。

我的建议是使用#2,因为它会减少对您服务器的调用。在您的上传页面上,您只需计算一次容器上的 SAS,然后在用户选择文件并上传文件时继续插入文件名。事实上,我们在我正在开发的一个产品中使用了这种方法。

于 2014-10-24T06:35:33.690 回答