unity-game-engineazure-storageunity-webglazurite

Pulling files from Azurite in Unity fails


I am trying to use an OBJ file from Azure storage in my unity scene, which I will run as an website application. I have azurite running and a container created with files in it. I can see the file in Azure Storage Explorer, under Emulator->Blob Container->MyContainer. I created Azurite running this docker compose script:

azurite:
    image: mcr.microsoft.com/azure-storage/azurite
    container_name: "azurite"
    hostname: azurite
    restart: always
    ports:
      - "10000:10000"
      - "10001:10001"
      - "10002:10002"

In Azure Storage Explorer, I can see this is my connection string:

AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;

And when I am in Azure Storage Explorer, and I copy the URL for my file, I can see that it is:

http://127.0.0.1:10000/devstoreaccount1/MyContainer/MyFile.jpg

In my Unity script, I call this code:

private string DownloadString(string url)
{
    using (WebClient client = new WebClient())
    {   
        client.Headers.Add("Authorization", "SharedKey devstoreaccount1:Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==");
        return client.DownloadString(url);
    }
}

and call it like this

private void myTest(){
     string objUrl = "http://127.0.0.1:10000/devstoreaccount1/MyContainer/MyFile.obj";
     string objData = DownloadString(objUrl);
}

But I get this error:

System.Net.WebException: The remote server returned an error: (403) Server failed to authenticate the request. Make sure the value of the Authorization header is formed correctly including the signature..

EDIT

@Venkatesan thank you so much for this very thorough response! I have tried to use your code and run it, but I am still getting the same 403 error. I have moved my code out into a console app, just for testing purposes. I am not sure if I am using the wrong account credentials or if there is an issue with Docker? I can see in docker that the container is getting the request, but it still fails.

For the Access-Key, I use the Key specified in MS Azure Storage Explorer, which I assume is the default key setup, since I did not specify it in my Docker Compose: Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==

For the container, I use the value of azurite as it is defined in my Docker Compose file. I did notice that when the Docker Compose ran, it did not create a Blob Container, so I created one and called that azurite as well.

And then for the URL, I just used the URL as defined when I right click on the image, in Storage Explorer, and copy the URL:

http://127.0.0.1:10000/devstoreaccount1/azurite/MyFile.obj

so my request looks like this:

using (WebClient client = new WebClient())
{   
   client.Headers.Add("Authorization", $"SharedKey devstoreaccount1:{authorization}");
   client.Headers.Add("x-ms-date", date);
   client.Headers.Add("x-ms-version", apiVersion);
            
 client.DownloadString("http://127.0.0.1:10000/devstoreaccount1/azurite/MyFile.obj");
}

But when the console app runs, and I create the signature and pass that in, it still fails with a 403 error.


Solution

  • I had to make the following changes and this worked:

    + "/{0}/{1}/{2}", Account, Container, blob); should change to + "/{0}/{0}/{1}/{2}", Account, Container, blob);

    client.Headers.Add("Authorization", $"SharedKey devstoreaccount1:{authorization}"); should change to client.Headers.Add("Authorization", authorization);