Azure / azure-storage-cpp

Microsoft Azure Storage Client Library for C++
http://azure.github.io/azure-storage-cpp
Apache License 2.0
132 stars 147 forks source link

connection string works in Azure Storage Explorer, but fails on some machines with azure-storage-cpp #243

Open fferri opened 5 years ago

fferri commented 5 years ago

I have a C++ client application which connects to Azure Storage. This is what I have in the Client class constructor:

Client::Client() {
    ...
   storage_connection_string = U("...the connection string...");
   storage_account = azure::storage::cloud_storage_account::parse(storage_connection_string);
   blob_client = storage_account.create_cloud_blob_client();
   container = blob_client.get_container_reference(U("generalstorage"));
}

On my machines (Ubuntu 16, macOS) it works fine.

On some other machines (Ubuntu 16, Ubuntu 18) it fails with an azure::storage::storage_exception:

Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

It seems it is not a problem of clock.

Also, on the machine where creating the client fails, the same connection string works in Microsoft Azure Storage Explorer.

katmsft commented 5 years ago

Thanks for reporting the issue. There are however some information that needs to be clarified by you:

  1. Are the dependencies' version exactly the same for the success and failed Ubuntu 16?
  2. What is the version of Azure Storage client library are you using?
  3. Are you using key authorization or SAS authorization?
  4. Do you have the request ID for the failed request, so that we can take a look at the server log to find out what could be the problem?
  5. Can you enable and collect the logs so that we can have more information of the request?
fferri commented 5 years ago

We have a connection string in the format DefaultEndpointsProtocol=https;Account Name=bluecloudfilestorage;AccountKey=...;BlobEndpoint=...;Queue Endpoint=...;TableEndpoint=...;FileEndpoint=...;.

Enabled logging (i.e. with azure::storage::operation_context::set_default_log_level(azure::storage::client_log_level::log _level_verbose);).

On the failing machine we have:

[2019-03-19 10:59:57.156691] [0x00007fcd1f111980] [trace]   3F43EA42-8983-4AC8-A0C3-C08210421A4B : This operation can only be executed against the primary storage location.
[2019-03-19 10:59:57.156823] [0x00007fcd1f111980] [info]    3F43EA42-8983-4AC8-A0C3-C08210421A4B : Starting HEAD request to https://bluecloudfilestorage.blob.core.windows.net/generalstorage?restype=container
[2019-03-19 10:59:57.156951] [0x00007fcd1f111980] [trace]   3F43EA42-8983-4AC8-A0C3-C08210421A4B : StringToSign: HEAD............x-ms-client-request-id:3F43EA42-8983-4AC8-A0C3-C08210421A4B.x-ms-date:Die, 19 Mär 2019 09:59:57 GMT.x-ms-version:2017-07-29./bluecloudfilestorage/generalstorage.restype:container
[2019-03-19 10:59:57.383938] [0x00007fcd01848700] [info]    3F43EA42-8983-4AC8-A0C3-C08210421A4B : Response received. Status code = 403. Reason = Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
[2019-03-19 10:59:57.384779] [0x00007fcd01848700] [warning] 3F43EA42-8983-4AC8-A0C3-C08210421A4B : Failed request ID = a841ede2-a01e-0096-1c3a-de8613000000
[2019-03-19 10:59:57.385224] [0x00007fccfd840700] [warning] 3F43EA42-8983-4AC8-A0C3-C08210421A4B : Exception thrown while processing response: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
[2019-03-19 10:59:57.385350] [0x00007fccfd840700] [error]   3F43EA42-8983-4AC8-A0C3-C08210421A4B : Retry policy did not allow for a retry, so throwing exception: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
terminate called after throwing an instance of 'azure::storage::storage_exception'
  what():  Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.

I noticed that the string to sign is StringToSign: HEAD............x-ms-client-request-id:3F43EA42-8983-4AC8-A0C3-C08210421A4B.x-ms-date:Die, 19 Mär 2019 09:59:57 which contains the date in local format (German).

If we run export LC_ALL=C LANG=C before launching the program, it works fine:

[2019-03-19 11:05:42.075165] [0x00007f5b62e51980] [trace]   80993A27-490A-4307-9F92-BC03515F32EF : This operation can only be executed against the primary storage location.
[2019-03-19 11:05:42.075361] [0x00007f5b62e51980] [info]    80993A27-490A-4307-9F92-BC03515F32EF : Starting HEAD request to https://bluecloudfilestorage.blob.core.windows.net/generalstorage?restype=container
[2019-03-19 11:05:42.075539] [0x00007f5b62e51980] [trace]   80993A27-490A-4307-9F92-BC03515F32EF : StringToSign: HEAD............x-ms-client-request-id:80993A27-490A-4307-9F92-BC03515F32EF.x-ms-date:Tue, 19 Mar 2019 10:05:42 GMT.x-ms-version:2017-07-29./bluecloudfilestorage/generalstorage.restype:container
[2019-03-19 11:05:42.323215] [0x00007f5b43d85700] [info]    80993A27-490A-4307-9F92-BC03515F32EF : Response received. Status code = 200. Reason = OK
[2019-03-19 11:05:42.323479] [0x00007f5b43d85700] [info]    80993A27-490A-4307-9F92-BC03515F32EF : Successful request ID = 29ed9d2c-a01e-00e4-213b-de815c000000
[2019-03-19 11:05:42.323716] [0x00007f5b36d6b700] [info]    80993A27-490A-4307-9F92-BC03515F32EF : Operation completed successfully
...

(it has been a "lucky" condition to spot this problem today, as the abbreviated month name in German is identical to the abbreviated month name in English for most of the month names: Jan, Feb, Apr, Jun, Jul, Aug, Sep, Nov)

katmsft commented 5 years ago

That is great! I am glad that you figured out the problem. I will mark this as a good first read in case locale mixed things up for other customers as well. Please proceed to close the issue if you don't mind.

fferri commented 5 years ago

Are there any plans to fix this issue?

It seems in order to fix this, the date string in the string-to-sign must be rendered in a non-localised way.

katmsft commented 5 years ago

CPPRestsdk has pushed a fix to the dev branch. Can you verify if it solves your problem? There is nothing to be changed in this repository to adapt to the fix.