Как настроить параметр CORS для хранилища BLOB-объектов в Windows Azure

Я создал несколько контейнеров в лазурном хранилище, а также загрузил в эти контейнеры несколько файлов. Теперь мне нужно предоставить доступ на уровне домена к контейнеру/блобам. Итак, я попробовал это с уровня кода, как показано ниже.

        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());  

Но вышеприведенный код кажется рабочим, если я создаю все из кода (поправьте меня, если я ошибаюсь). Я также нахожу настройку, подобную приведенной ниже: >Здесь,

 <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>

Но я не понял, куда этот код нужно поместить. Я имею в виду в каком файле. Или есть ли какие-либо настройки для CORS при создании контейнера или большого двоичного объекта на портале Azure. Пожалуйста помогите. Любая помощь будет ценной. Спасибо!


person Rajaram Shelar    schedule 19.02.2015    source источник


Ответы (3)


Следующее отвечает на вопрос, который на самом деле был задан в заголовке. Похоже, что спрашивающий уже знал, как это сделать, в основном из своего кода, но вот мой ответ на это. К сожалению, примеры кода, предоставленные 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
        };
person Nicholas Petersen    schedule 01.10.2015

Позвольте мне попытаться ответить на ваш вопрос. Как вы знаете, Azure Storage предлагает REST API для управления содержимым хранилища. . Операция там Set Blob Service Properties и одна из вещей, которые вы там делаете это управление правилами CORS для службы BLOB-объектов. XML, который вы включили в вопрос, является полезной нагрузкой запроса для этой операции. Упомянутый вами код С# на самом деле является клиентской библиотекой хранилища, которая по сути является оболочкой этого REST API, написанного на .Net. Поэтому, когда вы используете приведенный выше код, он фактически вызывает REST API и отправляет XML.

Теперь, что касается вариантов настройки правил CORS, есть несколько способов добиться этого. Если вы заинтересованы в их программной настройке, вы можете либо написать код, использующий REST API, либо напрямую использовать клиентскую библиотеку хранилища .Net, как вы сделали выше. Вы можете просто создать консольное приложение, поместить туда код и выполнить его, чтобы установить правило CORS. Если вы ищете какие-либо инструменты для этого, вы можете попробовать один из следующих инструментов:

person Gaurav Mantri    schedule 19.02.2015
comment
Спасибо за ответ. Я поместил код С# в событие global.asax application_start и попытался установить правило CORS для конкретного контейнера. Но когда я пытался получить доступ к любому конкретному URL-адресу из браузера, он загружал этот файл, что означает, что логика CORS не работает. Можете подсказать как это реализовать. - person Rajaram Shelar; 20.02.2015
comment
Я сейчас в замешательстве :P. CORS полезен, когда вы хотите получить доступ или вызвать REST API с помощью JavaScript. Если я не ошибаюсь, вас больше интересует ограничение доступа к контейнеру. Я прав? - person Gaurav Mantri; 20.02.2015
comment
@ Gaurav Mantri : Да.. ты меня понял.. мне нужно именно то, что ты говоришь - person Rajaram Shelar; 20.02.2015
comment
Что вам нужно сделать, так это изменить ACL-список контейнера на Private, если вы не хотите, чтобы кто-то другой загружал большой двоичный объект напрямую, введя URL-адрес большого двоичного объекта. Я считаю, что вы можете сделать это на самом портале. - person Gaurav Mantri; 20.02.2015
comment
Ага. Я сделал это. Но я хочу получить изображения BLOB-объектов из image src. Если я сделаю это приватным, они будут недоступны. Можем ли мы разрешить хранение больших двоичных объектов для запросов, поступающих с определенного домена (мой веб-сайт)? - person Rajaram Shelar; 21.02.2015
comment
Извините, что навязываю это, но где мне открыть консоль и ввести эти команды ‹CorsRule›, например, в Azure Storage Explorer (версия 6, предварительная версия 3)? - person Andreas Galster; 25.03.2015

Не рекомендуется предоставлять доступ на уровне домена к вашим контейнерам. Вы можете сделать контейнер частным, загрузить файлы (создать большой двоичный объект), а затем поделиться им с помощью политики общего доступа.

Приведенный ниже код может вам помочь.

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>
person Pramod    schedule 12.02.2016