Получите доступ к файлу BLOB через URI через веб-браузер, используя новый контроль доступа на основе AAD - PullRequest
4 голосов
/ 26 марта 2019

С объявлением о поддержке хранилища Azure для управления доступом на основе Azure Active Directory возможно ли обслуживать большой двоичный объект (определенный файл) через веб-браузер только по его URI?

Вариант использования, который я хочу упростить, дает нескольким людям доступ к файлам в BLOB-объекте без необходимости добавлять токен SAS в URI.Вместо этого было бы замечательно запустить типичный поток OAuth при попытке открыть простой URI в своем веб-браузере.

В моем случае мы хотим предоставить доступ к файлам, которые были загружены пользователями в хранилище больших двоичных объектов через нашего бота поддержки, построенного на платформе Microsoft Bot.Ссылки в нашей системе поддержки должны быть доступны для агента поддержки в выбранном им веб-браузере.

Если этот вариант использования поддерживается данным объявлением или он работает только для кодированных потоков OAuth, то есть нам все еще нужно реализовать некоторыекод?

Если да, есть ли хороший пример того, как запустить поток OAuth из приложения-функции Azure и использовать полученный токен для загрузки файла (через конечную точку REST хранилища Azure)?

Ответы [ 2 ]

1 голос
/ 29 марта 2019

Хотя этот ответ технически правильный, он не был прямым ответом на мой первоначальный вопрос.

Я искал способ предоставить прямой URI любого блоба для бизнес-пользователей, чтобы они могли просто открыть его в любом веб-браузере и просмотреть файл.

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

После изучения этого вопроса я могу ответить на свой вопрос:

С объявлениемподдержки хранилища Azure для управления доступом на основе Azure Active Directory, возможно ли обслуживать большой двоичный объект (определенный файл) через веб-браузер только по его URI?

Нет , это невозможно.Точнее говоря, простое открытие прямого URI для блоба в браузере не запускает поток OAuth.Вместо этого он всегда будет давать вам ответ ResourceNotFound, если вы не предоставите токен запроса SAS или не установите для большого двоичного объекта значение public.Оба решения плохие с точки зрения безопасности (когда вовлечены обычные пользователи) и, очевидно, плохой UX.

Решение

Ища способ архивировать именно то, что я хочу, я пришел к идееФункция Azure, обслуживающая вложение любому бизнес-пользователю, передавая fileName URI, создающего путь с использованием шаблона маршрута.

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

Однако этого недостаточно, и настройка всех частей решения не проста.Вот почему я делюсь этим.

TL; высокоуровневые шаги DR:

  1. Создание нового приложения функции (рекомендуется v2)
  2. Включение функции приложения для аутентификация (easyAuth)
  3. Создание субъекта службы (или регистрация приложения) для приложения-функции (подразумевается в шаге 2)
  4. Добавление дополнительной разрешенной аудитории токенов https://storage.microsoft.com при регистрации приложения
  5. Измените манифест регистрации приложения, включив в него разрешение API хранилища Azure (см. специальные замечания ниже)
  6. Измените authSettings в проводнике ресурсов Azure, включив additionalLoginParams для ответа токенаи resourceId
  7. Предоставьте как минимум Storage Blob Data Reader разрешению для BLOB-объекта всем пользователям, имеющим доступ к файлам
  8. Разверните свое функциональное приложение, вызовите его, получите доступ к токену пользователявызовите хранилище больших двоичных объектов и представьте результат пользователю (см. примеры кода ниже)

Замечания о разрешении API Azure Storage и токене доступа (шаги 5 и 6)

Как указано в последней документации для поддержки аутентификации AAD в хранилище Azure, приложение должно увеличить user_impersonation область полномочий для resourceId https://storage.azure.com/.К сожалению, в документации не указано, как установить это разрешение API, поскольку оно не отображается на портале (по крайней мере, я его не нашел).

Таким образом, единственный способ - настроить его через глобальный GUID (можно найти в Интернете), отредактировав манифест регистрации приложения непосредственно на портале Azure.

Обновление : Как оказалось, поиск правильного разрешения на портале является ошибкой.Смотрите мой ответ здесь .Изменение манифеста вручную приводит к тому же результату, но непосредственно делать это на портале гораздо удобнее.

Manifest

"requiredResourceAccess": [
    {
        "resourceAppId": "e406a681-f3d4-42a8-90b6-c2b029497af1",
        "resourceAccess": [
            {
                "id": "03e0da56-190b-40ad-a80c-ea378c433f7f",
                "type": "Scope"
            }
        ]
    },
    {
        "resourceAppId": "00000002-0000-0000-c000-000000000000",
        "resourceAccess": [
            {
                "id": "311a71cc-e848-46a1-bdf8-97ff7156d8e6",
                "type": "Scope"
            }
        ]
    }
]

Первыйодин из них - это область действия user_impersonation в хранилище Azure, а второй - разрешение для графика для User.Read, что в большинстве случаев полезно или необходимо.

После загрузки измененного манифеста вы можете проверить его на вкладке Разрешения API регистрации вашего приложения.

Поскольку easyAuth использует конечную точку AAD v1, ваше приложение должно запрашивать эти разрешения статически, передавая resource=https://storage.azure.com/ при запуске потока OAuth.

Кроме того, для хранилища Azure требуется схема однонаправленного канала для заголовка аутентификации и, следовательно, необходим токен JWT.Чтобы получить токен JWT от конечной точки, нам нужно передать response_type=code id_token в качестве дополнительного параметра входа в систему.

И то, и другое можно сделать только через Исследователь ресурсов Azure или powershell.

Используя обозреватель ресурсов Azure, вы должны полностью перейти к authSettings в своем функциональном приложении и соответственно установить additionalLoginParams.

enter image description here

"additionalLoginParams": [
  "response_type=code id_token",
  "resource=https://storage.azure.com/"
]

enter image description here

Пример кода

Вот полный пример кода для простой функции лазури, используя все вышеперечисленноемеханизмы.

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;

namespace Controller.Api.v1.Org
{
    public static class GetAttachment
    {
        private const string defaultContentType = "application/octet-stream";

        [FunctionName("GetAttachment")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "v1/attachments")] HttpRequest req,
            ILogger log)    
        {
            if (!req.Query.ContainsKey("fileName"))
                return new BadRequestResult();

            // Set the file name from query parameter
            string fileName = req.Query["fileName"];

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);

            fileName = fileName ?? data?.name;

            // Construct the final uri. In this sample we have a applicaiton setting BLOB_URL
            // set on the function app to store the target blob
            var blobUri = Environment.GetEnvironmentVariable("BLOB_URL") + $"/{fileName}";

            // The access token is provided as this special header by easyAuth.
            var accessToken = req.Headers.FirstOrDefault(p => p.Key.Equals("x-ms-token-aad-access-token", StringComparison.OrdinalIgnoreCase));

            // Construct the call against azure storage and pass the user token we got from easyAuth as bearer
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken.Value.FirstOrDefault());
                client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate");
                client.DefaultRequestHeaders.Add("Accept", "*/*");
                client.DefaultRequestHeaders.Add("x-ms-version", "2017-11-09");

                // Serve the response directly in users browser. This code works against any browser, e.g. chrome, edge or even internet explorer
                var response = await client.GetAsync(blobUri);
                var contentType = response.Content.Headers.FirstOrDefault(p => p.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase));
                var byteArray = await response.Content.ReadAsByteArrayAsync();

                var result = new FileContentResult(byteArray, contentType.Value.Any() ? contentType.Value.First() : defaultContentType);

                return result;
            }
        }
    }
}
1 голос
/ 27 марта 2019

Если вы хотите использовать управление доступом на основе Azure Active Directory для хранилища, вам нужно получить токен доступа.Вот шаги для справки.

  1. Зарегистрируйте приложение

2. Назначьте встроенную роль RBAC этому приложению Это зависит от вас, какую роль назначить приложению.enter image description here

3. Получить токен доступа .enter image description here

4. Теперь с помощью токена доступа вы можете вызывать api остальной памяти.enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...