Azure / azure-storage-cpplite

Lite version of C++ Client Library for Microsoft Azure Storage
MIT License
25 stars 44 forks source link

request signing failed when accessing Azure Blob Storage on IoT Edge #24

Open spinosae opened 5 years ago

spinosae commented 5 years ago

I was trying to run the SDK on an Embedded Linux device running as IoT leaf to access Azure Blob Storage on IoT Edge. However authorization kept failing. Meanwhile Azure Storage .Net SDK worked just fine.

After some digging, I narrowed down the problem to request signing. The client side (leaf device) signed a different header compared to what sever (Blob Storage on IoT Edge) saw. For example, client signed the header as:

PUT

x-ms-client-request-id:4cb210a3-2560-4da4-85a2-8c76ddd10336
x-ms-date:Mon, 13 May 2019 03:14:11 GMT
x-ms-version:2018-03-28
/mymoxa2/cont1
restype:container

While the server saw:

PUT

x-ms-client-request-id:4cb210a3-2560-4da4-85a2-8c76ddd10336
x-ms-date:Mon, 13 May 2019 03:14:11 GMT
x-ms-version:2018-03-28
/mymoxa2/mymoxa2/cont1
restype:container

The difference was with resource path /mymoxa2/cont1 vs /mymoxa2/mymoxa2/cont1. It tracked down to shared_key_credential::sign_request function in storage_credential.cpp. My temporary hack was to append account name twice. Then it worked. I am not security expert and I bet you'll come up with a better fix.

katmsft commented 5 years ago

Thanks for reporting the issue. Can you also share the name of the blob you saw from .NET SDK and the full URL please?

spinosae commented 5 years ago

Thanks for reporting the issue. Can you also share the name of the blob you saw from .NET SDK and the full URL please?

Hi, in .NET SDK the resource path was /mymoxa2/mymoxa2/cont1 on both sides (cont1 was the container name, mymoxa2 was account name. edited in original post).

I figured resource path was supposed to be /[ACCOUNT_NAME]/[CONTAINER_PATH], where [CONATINER_PATH] was coded as [ACCOUNT_NAME]/[CONTAINER_NAME] in .NET SDK but without leading [ACCOUNT_NAME] in cpplite SDK. You may refer to 'GetCanonicalizedResourceString' in AuthenticationUtility.cs.

katmsft commented 4 years ago

Is it possible to also share the URI that you are accessing? I somehow cannot find the place where the behavior is different than .Net SDK's and cpp SDK's. Each of the 3 SDKs appends account name and url absolute path as the resource path.

Jinming-Hu commented 4 years ago

@spinosae I think this issue has been fixed in the latest 0.3.0 release. Feel free to let us know if you have further questions.