如何在windows azure中为Blob存储配置CORS设置

时间:2015-02-19 14:26:27

标签: c# azure azure-storage

我在azure存储中创建了几个容器,并将一些文件上传到这些容器中。现在我需要给容器/ blob提供域级访问权限。所以我从代码级别尝试了它,如下所示。

        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
        ServiceProperties blobServiceProperties = new ServiceProperties();
            blobServiceProperties.Cors.CorsRules.Add(new CorsRule(){
                AllowedHeaders = new List<string>() {"*"},
                ExposedHeaders = new List<string>() {"*"},
                AllowedMethods = CorsHttpMethods.Post | CorsHttpMethods.Put | CorsHttpMethods.Get | CorsHttpMethods.Delete ,
                AllowedOrigins = new List<string>() { "http://localhost:8080/"},
                MaxAgeInSeconds = 3600,
            });

          blobClient.SetServiceProperties(GetBlobServiceProperties());  

但是如果我从代码创建所有内容(如果我错了就纠正我),上面的代码似乎是有效的。我也找到类似Here下方的设置,

 <CorsRule>
  <AllowedOrigins>http://www.contoso.com, http://www.fabrikam.com</AllowedOrigins>
  <AllowedMethods>PUT,GET</AllowedMethods>
  <AllowedHeaders>x-ms-meta-data*,x-ms-meta-target,x-ms-meta-source</AllowedHeaders>
  <ExposedHeaders>x-ms-meta-*</ExposedHeaders>
  <MaxAgeInSeconds>200</MaxAgeInSeconds>
</CorsRule>

但是我没有得到这个代码必须放的地方。我的意思是在哪个文件中。或者从azure门户创建容器或blob时是否有任何CORS设置。请协助。任何帮助都会很明显。谢谢!

3 个答案:

答案 0 :(得分:12)

以下回答了标题中实际提出的问题。似乎提问者已经知道如何在他的代码中做到这一点,但这是我对此的回答。不幸的是,MS推出的代码示例远非容易或清晰,所以我希望这有助于其他人。在这个解决方案中,你只需要一个CloudStorageAccount实例,你可以从那时调用这个函数(作为扩展方法)。

//使用:

        // -- example usage (in this case adding a wildcard CORS rule to this account --

        CloudStorageAccount acc = getYourStorageAccount();

        acc.SetCORSPropertiesOnBlobService(cors => {
            var wildcardRule = new CorsRule() { AllowedMethods = CorsHttpMethods.Get, AllowedOrigins = { "*" } };
            cors.CorsRules.Add(wildcardRule);
            return cors;
        });

//代码:

    /// <summary>
    /// Allows caller to replace or alter the current CorsProperties on a given CloudStorageAccount.
    /// </summary>
    /// <param name="storageAccount">Storage account.</param>
    /// <param name="alterCorsRules">The returned value will replace the 
    /// current ServiceProperties.Cors (ServiceProperties) value. </param>
    public static void SetCORSPropertiesOnBlobService(this CloudStorageAccount storageAccount,
        Func<CorsProperties, CorsProperties> alterCorsRules)
    {
        if (storageAccount == null || alterCorsRules == null) throw new ArgumentNullException();

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

        ServiceProperties serviceProperties = blobClient.GetServiceProperties();

        serviceProperties.Cors = alterCorsRules(serviceProperties.Cors) ?? new CorsProperties();

        blobClient.SetServiceProperties(serviceProperties);
    }

考虑CorsRule类的属性可能会有所帮助:

        CorsRule corsRule = new CorsRule() {
            AllowedMethods = CorsHttpMethods.Get,       // Gets or sets the HTTP methods permitted to execute for this origin
            AllowedOrigins = { "*" },                   // (IList<string>) Gets or sets domain names allowed via CORS.
            //AllowedHeaders = { "*" },                 // (IList<string>) Gets or sets headers allowed to be part of the CORS request
            //ExposedHeaders = null,                    // (IList<string>) Gets or sets response headers that should be exposed to client via CORS
            //MaxAgeInSeconds = 33333                   // Gets or sets the length of time in seconds that a preflight response should be cached by browser
        };

答案 1 :(得分:4)

让我试着回答你的问题。如您所知,Azure Storage提供了用于管理存储内容的REST API。有Set Blob Service Properties的操作,你在那里做的一件事是管理blob服务的CORS规则。您在问题中包含的XML是此操作的请求有效负载。您提到的C#代码实际上是存储客户端库,它本质上是用.Net编写的这个REST API的包装器。因此,当您使用上面的代码时,它实际上会调用REST API并发送XML。

现在有关设置CORS规则的选项,您可以通过几种方式实现这一目标。如果您对以编程方式设置它们感兴趣,那么您可以编写一些使用REST API的代码,也可以直接使用.Net存储客户端库,如上所述。您可以简单地创建一个控制台应用程序,将代码放在那里并执行它以设置CORS规则。如果您正在寻找一些工具来执行此操作,那么您可以尝试以下工具之一:

答案 2 :(得分:-1)

为您的容器提供域级访问权限不是一个好主意。您可以将容器设为私有,上载文件(创建blob),然后使用共享访问策略共享它。

以下代码可以为您提供帮助。

static void Main(string[] args)
        {
            var account = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorageAccount"].ConnectionString);
            var bClient = account.CreateCloudBlobClient();
            var container = bClient.GetContainerReference("test-share-container-1");
            container.CreateIfNotExists();

            // clear all existing policy
            ClearPolicy(container);

            string newPolicy = "blobsharepolicy";
            CreateSharedAccessPolicyForBlob(container, newPolicy);
            var bUri = BlobUriWithNewPolicy(container, newPolicy);

            Console.ReadLine();
        }

        static void ClearPolicy(CloudBlobContainer container)
        {
            var perms = container.GetPermissions();
            perms.SharedAccessPolicies.Clear();
            container.SetPermissions(perms);
        }       

        static string BlobUriWithNewPolicy(CloudBlobContainer container, string policyName)
        {
            var blob = container.GetBlockBlobReference("testfile1.txt");
            string blobContent = "Hello there !!";
            MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(blobContent));
            ms.Position = 0;
            using (ms)
            {
                blob.UploadFromStream(ms);
            }

            return blob.Uri + blob.GetSharedAccessSignature(null, policyName);
        }

        static void CreateSharedAccessPolicyForBlob(CloudBlobContainer container, string policyName)
        {
            SharedAccessBlobPolicy sharedPolicy = new SharedAccessBlobPolicy()
            {
                SharedAccessExpiryTime = DateTime.UtcNow.AddHours(24),
                Permissions = SharedAccessBlobPermissions.Write | SharedAccessBlobPermissions.Read
            };
            var permissions = container.GetPermissions();            
            permissions.SharedAccessPolicies.Add(policyName, sharedPolicy);
            container.SetPermissions(permissions);
        }


<connectionStrings>
    <add name="AzureStorageAccount" connectionString="DefaultEndpointsProtocol=https;AccountName=[name];AccountKey=[key]" />
  </connectionStrings>