Невозможно реализовать доступ службы веб-приложения Azure к контейнеру хранилища Azure с помощью MSI. - PullRequest
0 голосов
/ 23 июня 2019

У меня есть группа ресурсов Azure, которая содержит службу веб-приложений и хранилище с контейнером BLOB. Мое веб-приложение (.NET Core) пытается извлечь и показать изображение из контейнера. Контейнер не имеет публичного доступа к контенту (уровень доступа приватный). Я создал системную идентификацию для моего приложения и дал ему роль Reader в управлении доступом к хранилищу (IAM).

Вот так я получаю доступ к BLOB-объектам в коде приложения:

const string blobName = "https://storagename.blob.core.windows.net/img/Coast.jpg";
string storageAccessToken = await GetStorageAccessTokenAsync();
var tokenCredential = new TokenCredential(storageAccessToken);
var storageCredentials = new StorageCredentials(tokenCredential);
var blob = new CloudBlockBlob(new Uri(blobName), storageCredentials);
ImageBlob = blob.Uri;

GetStorageAccessTokenAsync () делает это:

var tokenProvider = new AzureServiceTokenProvider();
return await tokenProvider.GetAccessTokenAsync("https://storage.azure.com/");

Затем изображение отображается как

<img src="@Model.ImageBlob" />

Я не получаю никаких исключений в своем коде, но изображение из контейнера BLOB не отображается с ошибкой 404 (указанный ресурс не существует) в консоли браузера. Когда я изменяю уровень доступа контейнера на «blob» (публичный доступ), приложение работает нормально, и изображение отображается. Видимо, что-то не так с получением части учетных данных, но я не смог найти ни рабочего примера, ни подробных объяснений, как это на самом деле должно работать. Любая помощь очень ценится.

UDPATE: Спасибо всем, кто откликнулся. Похоже, у меня тут две проблемы.

1) Я не получаю учетные данные должным образом. Я вижу, что созданный мной объект "AzureServiceTokenProvider" (Microsoft.Azure.Services.AppAuthentication) имеет пустое свойство PrincipalUsed во время выполнения.

Мое приложение развернуто в службе приложений Azure, у которой есть удостоверение, управляемое системой, и этому удостоверению (субъекту службы) предоставлены разрешения в хранилище Azure (я изменил разрешение с устройства чтения учетных записей на средство чтения данных BLOB-объектов хранилища, как было предложено).

Разве он не должен получить все данные, необходимые из текущего контекста? Если нет, то что я могу сделать здесь?

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

Но все же - каков общий способ сделать это в моем случае? Я имею в виду, что нет общего доступа к хранилищу, и я использую «CloudBlockBlob» для доступа к изображениям.

Ответы [ 3 ]

1 голос
/ 24 июня 2019

Считыватель дает доступ для чтения плоскости управления, но не плоскости данных. Роль, которую вам нужно - это Storage Blob Data Reader, который дает доступ для чтения содержимого BLOB-объектов.

Для получения более подробной информации об этом: https://docs.microsoft.com/en-us/azure/role-based-access-control/role-definitions#data-operations-example

0 голосов
/ 07 июля 2019

Наконец-то я получил его на работу. Прежде всего, часть кода, касающаяся получения токена и образа из хранилища Azure, была в порядке. Вторую проблему с отображением изображения в приложении RazorPages я решил, используя следующий код:

<form asp-page-handler="GetImage" method="get">
    <img src="/MyPageName?handler=GetImage" />
</form>

и соответствующий код в модели:

public async Task<ActionResult> OnGetGetImageAsync()
{
   //getting image code and returning FileContentResult
}

Но я все еще думаю: есть ли более простой способ сделать это? Что-то вроде добавления коллекции изображений в модель, заполнения ее с помощью обработчика «OnGet ...» и последующего отображения ее содержимого в представлении. Я не нашел способа использовать свойства модели в теге <img>. У кого-нибудь есть предложения?

0 голосов
/ 27 июня 2019

Когда вы используете <img src="@Model.ImageBlob" />, в запросе браузер не отправляет заголовок авторизации. В вашем коде вы выбираете токен, но токен не отправляется в заголовке авторизации при получении изображения. Итак, API хранилища считает, что это анонимный запрос. По этой причине вы получаете 404.

Вам нужно отправить код авторизации при загрузке изображения. Этот код работает для меня

public async Task<ActionResult> Image()
        {
            const string blobName = "https://storage.blob.core.windows.net/images/image.png";
            string storageAccessToken = await GetStorageAccessTokenAsync().ConfigureAwait(false);

            var tokenCredential = new TokenCredential(storageAccessToken);
            var storageCredentials = new StorageCredentials(tokenCredential);

            var blob = new CloudBlockBlob(new Uri(blobName), storageCredentials);
            Stream blobStream = blob.OpenRead();
            return File(blobStream, blob.Properties.ContentType, "image.png");
        }

В представлении я использую

<img src="/Home/Image" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...