【问题标题】:Upload files to Azure Storage from Azure VM using SDK azblob and Managed Service Identity使用 SDK azblob 和托管服务标识将文件从 Azure VM 上传到 Azure 存储
【发布时间】:2021-04-04 03:54:40
【问题描述】:

我正在尝试使用 Go SDK for Azure storage 从附加了 Azure 托管标识的 Azure VM 将文件上传到 azure 存储容器。我还使用Azure auth 使用MSIConfig 创建一个ServicePrincipalToken。但是我收到一个错误

RESPONSE Status: 400 Authentication information is not given in the correct format. Check the value of Authorization header.

有人可以帮我理解我缺少什么吗?

我使用的脚本(example 的修改形式):

// main.go
package main

import (
    "log"
    "fmt"
    "context"
    "net/url"
    "strings"
    "github.com/Azure/azure-storage-blob-go/azblob"
    "github.com/Azure/go-autorest/autorest/azure/auth"
)

func main() {
    azureServicePrincipalToken, err := auth.NewMSIConfig().ServicePrincipalToken()
    if err != nil {
        log.Fatal(err)
    }

    accountName := "<TESTSA>"
    containerName := "<TESTCONTAINER>"

    // Create a BlockBlobURL object to a blob in the container (we assume the container already exists).
    u, _ := url.Parse(fmt.Sprintf("https://%s.blob.core.windows.net/%s/readme.txt", accountName, containerName))
    credential := azblob.NewTokenCredential(azureServicePrincipalToken.Token().AccessToken, nil)
    if err != nil {
        log.Fatal(err)
    }
    blockBlobURL := azblob.NewBlockBlobURL(*u, azblob.NewPipeline(credential, azblob.PipelineOptions{}))

    log.Println(blockBlobURL)

    ctx := context.Background() // This example uses a never-expiring context

    // Perform UploadStreamToBlockBlob
    bufferSize := 2 * 1024 * 1024 
    maxBuffers := 3     
          
    _, err = azblob.UploadStreamToBlockBlob(ctx, strings.NewReader("Hello azblob"), blockBlobURL,
        azblob.UploadStreamToBlockBlobOptions{BufferSize: bufferSize, MaxBuffers: maxBuffers})

    if err != nil {
        log.Fatal(err)
    }
}

当我执行go run main.go 时,我收到以下错误:

2020/12/26 17:58:07 https://<TESTSA>.blob.core.windows.net/<TESTCONTAINER>/readme.txt
2020/12/26 17:58:07 write error: -> github.com/Azure/azure-storage-blob-go/azblob.newStorageError, /home/<MYUSER>/go/pkg/mod/github.com/!azure/azure-storage-blob-go@v0.12.0/azblob/zc_storage_error.go:42
===== RESPONSE ERROR (ServiceCode=) =====
Description=Authentication information is not given in the correct format. Check the value of Authorization header.
RequestId:f30c063e-901e-0046-2cb0-db4781000000
Time:2020-12-26T17:58:07.7810745Z, Details:
   Code: InvalidAuthenticationInfo
   PUT https://<TESTSA>.blob.core.windows.net/<TESTCONTAINER>/readme.txt?blockid=j%2BItsAdqRN6EScZ3S2r8QwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%3D%3D&comp=block&timeout=61
   Authorization: REDACTED
   Content-Length: [12]
   User-Agent: [Azure-Storage/0.12 (go1.13.9; linux)]
   X-Ms-Client-Request-Id: [21638ec4-138c-434d-4b53-d13924e51966]
   X-Ms-Version: [2019-12-12]
   --------------------------------------------------------------------------------
   RESPONSE Status: 400 Authentication information is not given in the correct format. Check the value of Authorization header.
   Content-Length: [298]
   Content-Type: [application/xml]
   Date: [Sat, 26 Dec 2020 17:58:07 GMT]
   Server: [Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0]
   X-Ms-Request-Id: [f30c063e-901e-0046-2cb0-db4781000000]


exit status 1

我还使用azcli 命令进行了验证,我能够将示例 txt 文件helloworld 上传到存储容器,没有任何挑战。我使用的命令:

az login --identity
az storage blob upload --container-name <TESTCONTAINER> --account-name <TESTSA> --name helloworld --file helloworld --auth-mode login

回复:

Finished[#############################################################]  100.0000%
{
  "etag": "\"0x8D8A9CCDD921BA7\"",
  "lastModified": "2020-12-26T18:34:22+00:00"
}

谢谢。

【问题讨论】:

    标签: azure go authentication azure-blob-storage azure-managed-identity


    【解决方案1】:

    您引用的代码示例使用 Shared KeyPut Blob API 进行授权,但不是 Azure AD。

    credential, err := NewSharedKeyCredential(accountName, accountKey)
    

    如果您想通过 ServicePrincipalToken 使用 Azure AD 进行授权,请参阅 Azure Active Directory authentication for Go

    applicationSecret := "APPLICATION_SECRET"
    
    spt, err := adal.NewServicePrincipalToken(
        *oauthConfig,
        appliationID,
        applicationSecret,
        resource,
        callbacks...)
    if err != nil {
        return nil, err
    }
    
    // Acquire a new access token
    err  = spt.Refresh()
    if (err == nil) {
        token := spt.Token
    }
    

    【讨论】:

    • 如果托管标识已附加到 VM,为什么还需要应用程序机密?我想使用 MSIConfig 而不是 OAuthConfig。我的全部目的是使用 MSI 将文件上传到容器。如果可能,请告诉我吗?
    • 尝试this 并将资源替换为https://storage.azure.com
    • 谢谢,我会调查的。您也可以编辑您的答案吗?因为它不是标题的用途,也没有涉及 MSI。
    猜你喜欢
    • 2017-01-04
    • 2020-10-29
    • 1970-01-01
    • 2018-09-05
    • 2015-05-20
    • 2020-08-10
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    相关资源
    最近更新 更多