Search code examples
c++azuresignatureshared

how to get shared access signature of Azure container by C++


I want to use C++ Azure API to generate a Shared Access Signature for a container on Azure and get the access string. But cannot find any good example. Almost all examples are in C#. Only found this, https://learn.microsoft.com/en-us/azure/storage/files/storage-c-plus-plus-how-to-use-files

Here is what I did,

    // Retrieve a reference to a previously created container.
    azure::storage::cloud_blob_container container = blob_client.get_container_reference(s2ws(eventID));

    // Create the container if it doesn't already exist.
    container.create_if_not_exists();

    // Get the current permissions for the event.
    auto blobPermissions = container.download_permissions();

    // Create and assign a policy
    utility::string_t policy_name = s2ws("Signature" + eventID);

    azure::storage::blob_shared_access_policy policy = azure::storage::blob_shared_access_policy();

    // set expire date
    policy.set_expiry(utility::datetime::utc_now() + utility::datetime::from_days(10));

    //give read and write permissions
    policy.set_permissions(azure::storage::blob_shared_access_policy::permissions::read);

    azure::storage::shared_access_policies<azure::storage::blob_shared_access_policy> policies;
    //add the new shared policy
    policies.insert(std::make_pair(policy_name, policy));

    blobPermissions.set_policies(policies);
    blobPermissions.set_public_access(azure::storage::blob_container_public_access_type::off);

    container.upload_permissions(blobPermissions);

    auto token = container.get_shared_access_signature(policy, policy_name);

After run this, I can see the policy is successfully set on the container, but the token got by the last line is not right. And there will always be an exception when exiting this function, the breakpoint locates in _Deallocate().

Could someone tell me what's wrong with my code? Or some examples about this? Thank you very much.

Edited

The token I got looks like,

"sv=2016-05-31&si=Signature11111122222222&sig=JDW33j1Gzv00REFfr8Xjz5kavH18wme8E7vZ%2FFqUj3Y%3D&spr=https%2Chttp&se=2027-09-09T05%3A54%3A29Z&sp=r&sr=c"

By this token, I couldn't access my blobs. The right token created by "Microsoft Azure Storage Explorer" using this policy looks like,

?sv=2016-05-31&si=Signature11111122222222&sr=c&sig=9tS91DUK7nkIlIFZDmdAdlNEfN2HYYbvhc10iimP1sk%3D

About the exception, I put all these code in a function. If without the last line, everything is okay. But if added the last line, while exiting this function, it will throw an exception and said a breakpoint was triggered. It stopped at the last line of _Deallocate() in "C:\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.10.25017\include\xmemory0",

::operator delete(_Ptr);

Have no idea why this exception being thrown and how to debug because it seems it cannot be caught by my code.

Edited

After changed the last line to,

auto token = container.get_shared_access_signature(azure::storage::blob_shared_access_policy(), policy_name);

The returned token is right, I can access my blobs by using it. But the annoying exception is still there :-(

Edited

Just found the exception only happened when building in Debug. If in Release, everything is ok. So maybe it's related to compiling environment.


Solution

  • When creating a Shared Access Signature (SAS), there are a few permissions you set: SAS Start/Expiry, Permissions, IP ACLing, Protocol restrictions etc. Now what you could do is create an access policy on the blob container with these things, create an ad-hoc SAS (i.e. without access policy) with these things or combine these two to create a SAS token.

    One key thing to keep in mind is that if something is defined in an access policy, you can't redefine them when creating a SAS. So for example, let's say you create an access policy with just Read permission and nothing else, then you can't provide any permissions when creating a SAS token while using this access policy. You can certainly define the things which are not there in the access policy (for example, you can define a SAS expiry if it is not defined in access policy).

    If you look at your code (before edit), what you're doing is creating an access policy with some permissions and then creating a SAS token using the same permissions and access policy. That's why it did not work. However when you created a SAS token from Microsoft's Storage Explorer, you will notice that it only included the access policy (si=Signature11111122222222) and none of the other parameters and that's why it worked.

    In your code after edit you did not include any permissions but only used the access policy (in a way you did what Storage Explorer is doing) and that's why things worked after edit.

    I hope this explains the mystery behind not working/working SAS tokens.