Я пытаюсь загрузить некоторые данные из хранилища BLOB-объектов Azure в Go через официальный azure-sdk-for-go
.
Чтобы настроить среду разработки, я успешно вошел в систему через az login
. Я проверил, что к большому двоичному объекту можно получить доступ через CLI:
az storage blob download --container-name [container-name] --name [blob-name] --account-name [storage-account-name] -f out.txt
Это работает, как и ожидалось. Чтобы получить файл unsing go, я использую следующий фрагмент (в качестве воспроизводящего файла):
func getBlob(account, container, object string) ([]byte, error) {
blobPath := fmt.Sprintf("https://%s.blob.core.windows.net/%s/%s", uri.Host, container, object)
ctx := context.Background()
credential, err := azidentity.NewDefaultAzureCredential(nil)
if err != nil {
return []byte{}, err
}
blobClient, err := azblob.NewBlockBlobClient(blobPath, credential, nil)
if err != nil {
return []byte{}, err
}
get, err := blobClient.Download(ctx, nil)
if err != nil {
return []byte{}, err
}
downloadedData := &bytes.Buffer{}
reader := get.Body(&azblob.RetryReaderOptions{})
_, err = downloadedData.ReadFrom(reader)
if err != nil {
return []byte{}, err
}
err = reader.Close()
if err != nil {
return []byte{}, err
}
data = downloadedData.Bytes()
return data, nil
}
При входе в систему через az login
я ожидаю, что azidentity.NewDefaultAzureCredential(nil)
будет использовать этот сеанс/сертификаты (см. https://docs.microsoft.com/en-us/azure/developer/go/azure-sdk-authentication?tabs=bash#-option-3-sign-in-with-azure-cli), однако это не работает, как ожидалось. Ошибка, которую я получаю, следующая:
===== RESPONSE ERROR (ErrorCode=AuthorizationPermissionMismatch) =====
Description=This request is not authorized to perform this operation using this permission.
RequestId:b078ec61-xxxx-xxxx-xxxx-604682000000
Time:2022-05-05T10:24:18.8093649Z, Details: (none)
exit status 255
Что мне не хватает?
(Я работаю с AWS, поэтому, скорее всего, я делаю предположения о том, как все должно работать, основываясь на этом опыте.)
DeepDave-MT Спасибо за указание. Согласно обсуждению в проблеме, которую вы связали, проблема, по-видимому, коренится в разрешениях. В моем случае доступ, по-видимому, работает с использованием az
CLI. С теми же разрешениями (я работаю как владелец) я ожидаю, что мой код go будет работать, по крайней мере, с точки зрения разрешений. Однако есть вероятность, что azidentity.NewDefaultAzureCredential(nil)
не использует повторно учетные данные от az login
так, как я сейчас предполагаю.
По-видимому, взаимодействие с большими двоичными объектами не работает с учетными данными, предоставленными azidentity.NewDefaultAzureCredential()
. Для работы с большими двоичными объектами Azure требуются токены SAS или общие ключи. Вот пример функции, которую можно использовать для получения клиента для определенного большого двоичного объекта:
func getBlobClient(account, container, object string) (*azblob.BlockBlobClient, error) {
accountKey, ok := os.LookupEnv("AZURE_STORAGE_ACCOUNT_KEY")
if !ok {
return nil, errors.New("AZURE_STORAGE_ACCOUNT_KEY could not be found")
}
credential, err := azblob.NewSharedKeyCredential(account, accountKey)
if err != nil {
return nil, err
}
accountPath := fmt.Sprintf("https://%s.blob.core.windows.net/", account)
serviceClient, err := azblob.NewServiceClientWithSharedKey(accountPath, credential, nil)
if err != nil {
return nil, err
}
containerClient, err := serviceClient.NewContainerClient(container)
if err != nil {
return nil, err
}
blobClient, err := containerClient.NewBlockBlobClient(object)
if err != nil {
return nil, err
}
return blobClient, nil
}
Это использует переменную среды AZURE_STORAGE_ACCOUNT_KEY
для учетных данных.
Примеры, которые можно найти, довольно запутаны (и, возможно, неверны), вопрос открыт здесь:
https://github.com/Azure-Samples/storage-blobs-go-quickstart/issues/7
Это могут быть похожие проблемы: Используйте токен для подключения к контейнеру и Служба BLOB-объектов возвращает недокументированную ошибку AuthorizationPermissionMismatch.