简体   繁体   中英

Upload files to Azure Storage from Azure VM using SDK azblob and Managed Service Identity

I am trying to upload files to azure storage container using Go SDK for Azure storage from an Azure VM which has Azure Managed Identity attached to it. I am also using Azure auth to create a ServicePrincipalToken using MSIConfig . However I am receiving an error

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

Can someone please help me understand what I am missing?

Script I have used (modified form of the 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)
    }
}

When I execute go run main.go , I receive the following error:

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

I have also verified with the azcli command and I was able to upload a sample txt file helloworld to the storage container without any challenge. The commands I used:

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

Response:

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

Thank you.

The code sample you refer to authorizes with Shared Key and Put Blob API, but not Azure AD.

credential, err := NewSharedKeyCredential(accountName, accountKey)

If you would like to authorize with Azure AD by ServicePrincipalToken , see 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
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM