locked
Table $batch with SAS failing RRS feed

  • Question

  • I have pretty simple example of trying a TableBatchOperation operation using SAS that fails with: HTTP/1.1 415 Unsupported Media Type. Using standard authentication works fine.

    I can repeat this error using the net, node, and native REST calls, so my assumption is that there is something wrong on the server side.

    This is a showstopper from a security perspective due to my inability to control batch updates to specific partitions and rows.

    PS - using single row PUT works but when I have thousands of devices sending thousands of rows every minute, the processing costs explode...

        public sealed class CloudClientTest
        {
            private readonly ILogger<CloudClientTest> _logger;
            private const int AccessPolicyClockSkew = 15;   // new to account for clock skew
            private const int AccessExpiration = AccessPolicyClockSkew + 5;   // new to account for clock skew
    
            public CloudClientTest(IOptions<AzureConfiguration> azureOptions, ILoggerFactory loggerFactory)
            {
                _logger = loggerFactory.CreateLogger<CloudClientTest>();
                try
                {
                    CloudStorageAccount = CloudStorageAccount.Parse(azureOptions.Value.BlobConnectionString);
                }
                catch (Exception exStorage)
                {
                    _logger.LogError("could not initialize cloud storage", exStorage);
                    throw;
                }
            }
    
             public CloudStorageAccount CloudStorageAccount { get; }
    
            public async Task<CloudTable> EnsureTableAsync(string name, bool createIfNull = true)
            {
                var client = CloudStorageAccount.CreateCloudTableClient();
                name = name.Replace("-", string.Empty).ToLowerInvariant();
                var table = client.GetTableReference(name);
                if (!await table.ExistsAsync() && createIfNull)
                {
                    await table.CreateAsync();
                }
    
                try
                {
                    var policy = new SharedAccessTablePolicy()
                    {
                        SharedAccessStartTime = DateTime.UtcNow.AddMinutes(-AccessPolicyClockSkew),
                        SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(AccessExpiration),
                        Permissions = SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Update,
                    };
    
                    string sasToken = table.GetSharedAccessSignature(
                       policy,
                       null,
                       "0000",
                       "0000",
                       "0000",
                       "0002",
                       SharedAccessProtocol.HttpsOnly,
                       null
                       );
    
                    var id = new StorageCredentials(sasToken);
                    client = new CloudTableClient(table.Uri, id);
                    var sasTable = client.GetTableReference(name);
                    var batchOp = new TableBatchOperation();
                    batchOp.Add(TableOperation.InsertOrReplace(new TableEntity("0000", "0000")));
                    batchOp.Add(TableOperation.InsertOrReplace(new TableEntity("0000", "0001")));
                    batchOp.Add(TableOperation.InsertOrReplace(new TableEntity("0000", "0002")));
                    await sasTable.ExecuteBatchAsync(batchOp);
                }
                catch (Exception e)
                {
                    _logger.LogError("Testing SAS batch failed", e);
                }
                return table;
            }
    
        }
    

    POST https://ossiacodev.table.core.windows.net/site4ed7a35da1f345db8e2114afd5c2df98/$batch?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31& HTTP/1.1
    Connection: Keep-Alive
    Content-Type: multipart/mixed; boundary=batch_195a46d0-28e6-4fb1-aeef-7f80c6a67d96
    Accept-Charset: UTF-8
    User-Agent: Azure-Storage/8.1.4 (.NET Core)
    MaxDataServiceVersion: 3.0;NetFx
    DataServiceVersion: 3.0;
    x-ms-client-request-id: 33f801f7-6ea0-4cef-8928-68150b03f75d
    x-ms-version: 2016-05-31
    Content-Length: 2153
    Host: ossiacodev.table.core.windows.net
    
    --batch_195a46d0-28e6-4fb1-aeef-7f80c6a67d96
    Content-Type: multipart/mixed; boundary=changeset_e363e905-1218-4195-a240-4dc04a730390
    
    --changeset_e363e905-1218-4195-a240-4dc04a730390
    Content-Type: application/http
    Content-Transfer-Encoding: binary
    
    PUT https://ossiacodev.table.core.windows.net/site4ed7a35da1f345db8e2114afd5c2df98/site4ed7a35da1f345db8e2114afd5c2df98(PartitionKey='0000',RowKey='0000')?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31 HTTP/1.1
    Accept: application/json;odata=minimalmetadata
    Content-Type: application/json
    DataServiceVersion: 3.0;
    
    {}
    --changeset_e363e905-1218-4195-a240-4dc04a730390
    Content-Type: application/http
    Content-Transfer-Encoding: binary
    
    PUT https://ossiacodev.table.core.windows.net/site4ed7a35da1f345db8e2114afd5c2df98/site4ed7a35da1f345db8e2114afd5c2df98(PartitionKey='0000',RowKey='0001')?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31 HTTP/1.1
    Accept: application/json;odata=minimalmetadata
    Content-Type: application/json
    DataServiceVersion: 3.0;
    
    {}
    --changeset_e363e905-1218-4195-a240-4dc04a730390
    Content-Type: application/http
    Content-Transfer-Encoding: binary
    
    PUT https://ossiacodev.table.core.windows.net/site4ed7a35da1f345db8e2114afd5c2df98/site4ed7a35da1f345db8e2114afd5c2df98(PartitionKey='0000',RowKey='0002')?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31 HTTP/1.1
    Accept: application/json;odata=minimalmetadata
    Content-Type: application/json
    DataServiceVersion: 3.0;
    
    {}
    --changeset_e363e905-1218-4195-a240-4dc04a730390--
    --batch_195a46d0-28e6-4fb1-aeef-7f80c6a67d96--
    
    
    RESPONSE:
    
    HTTP/1.1 415 Unsupported Media Type
    Content-Type: application/xml;charset=utf-8
    Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
    x-ms-request-id: 9e0012eb-0002-0044-584a-6c66f1000000
    x-ms-version: 2016-05-31
    X-Content-Type-Options: nosniff
    Date: Sun, 03 Dec 2017 15:23:55 GMT
    Content-Length: 305
    
    <?xml version="1.0" encoding="utf-8"?><error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"><code>AtomFormatNotSupported</code><message xml:lang="en-US">Atom format is not supported.
    RequestId:9e0012eb-0002-0044-584a-6c66f1000000
    Time:2017-12-03T15:23:55.4680550Z</message></error>
    

    • Changed type vikranth s Monday, December 4, 2017 5:46 PM Question
    Monday, December 4, 2017 4:27 PM

Answers

  • Yes it was thanks...

    The $batch requests must be made at the root query string.

    POST https://ossiacodev.table.core.windows.net/site4ed7a35da1f345db8e2114afd5c2df98/$batch?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31& HTTP/1.1


    needs to be 

    POST https://ossiacodev.table.core.windows.net/$batch?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31& HTTP/1.1

    rich

    PS thanks for the help



    rich


    • Edited by osiaco Wednesday, February 21, 2018 7:05 PM
    • Marked as answer by Adam Smith (Azure) Wednesday, February 21, 2018 7:32 PM
    Wednesday, February 21, 2018 7:04 PM

All replies

  • There has been some discussion on this topic already in the following thread.

    https://stackoverflow.com/questions/39463917/azure-table-service-rest-api-json-format-is-not-supported

    If it doesn’t help I recommend you create a technical support ticket. The ticket enables you to work closely with the support engineers and get a quick resolution to your issue.

    Here is the   http://azure.microsoft.com/en-us/support/options/ to create support case.

    Do click on "Mark as Answer" on the post that helps you, this can be beneficial to other community members.

    Monday, December 4, 2017 5:47 PM
  • Thanks for the pointer, unfortunately the stackoverflow thread is unrelated to my problem...

    My error is specific to $batch with SAS key using the current version of the SDK.

    rich

    Monday, December 4, 2017 11:53 PM
  • Have you been able to create a support case?

    Do click on "Mark as Answer" on the post that helps you, this can be beneficial to other community members

    Tuesday, December 5, 2017 7:57 PM
  • yes thanks.

    rich

    Tuesday, December 5, 2017 7:58 PM
  • Rich was the issue already sorted on the support case or do you still need any help ?

    Thanks,
    Adam
    Wednesday, February 21, 2018 6:58 PM
  • Yes it was thanks...

    The $batch requests must be made at the root query string.

    POST https://ossiacodev.table.core.windows.net/site4ed7a35da1f345db8e2114afd5c2df98/$batch?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31& HTTP/1.1


    needs to be 

    POST https://ossiacodev.table.core.windows.net/$batch?sv=2016-05-31&tn=site4ed7a35da1f345db8e2114afd5c2df98&spk=0000&srk=0000&epk=0000&erk=0002&sig=RFMHgKAw%2FRTC7jBxH7j%2BSwDUyyGC%2FUBonioNL4WYfNU%3D&spr=https&st=2017-12-03T15%3A08%3A45Z&se=2017-12-03T15%3A43%3A45Z&sp=rau&api-version=2016-05-31& HTTP/1.1

    rich

    PS thanks for the help



    rich


    • Edited by osiaco Wednesday, February 21, 2018 7:05 PM
    • Marked as answer by Adam Smith (Azure) Wednesday, February 21, 2018 7:32 PM
    Wednesday, February 21, 2018 7:04 PM