none
Authorization Failure when accessing table.

    Question

  • I have set up a custom API to generate a SAS token for my Xamarin app.  Once I have received the token on the app, I connect to the table and try to run .ExistsAsync() to confirm that I can communicate with the table.  I'm running into an issue where I have generated a SAS properly (though I'm wondering if the start/end times are off), but I'm getting an Authorization Failure when I try to call ExistsAsync().  I have included below my SAS generation API, my Xamarin app methods calling ExistsAsync(), and the error message I am receiving.

    Custom API for SAS generation:

    module.exports = {
        "post": function (req, res, next) {
            var azure = require('azure-storage');
            var tableName = req.body.Table;
     
            // First 2 parameters are account name and key for your service
            var tableService = azure.createTableService('ACCOUNT_NAME', 'ACCOUNT_KEY', 'ACCOUNT_URL');
     
            // creating the table we want the token for - on the off chance it's not there yet
            tableService.createTableIfNotExists(tableName, function (err, result, response) {
                if (!err) {
                    var expiryDate = new Date();
                    var startDate = new Date();
                    expiryDate.setMinutes(startDate.getMinutes() + 100);
                    startDate.setMinutes(startDate.getMinutes() - 100);
     
     
                    var sharedAccessPolicy = {
                        AccessPolicy: {
                            Permissions: 'raud', // requesting read, add, update and delete
                            Start : startDate,
                            Expiry: expiryDate
                        },
                    };
     
                    
                    var tableSAS = tableService.generateSharedAccessSignature(tableName, sharedAccessPolicy);
                    res.send(200, { Token : tableSAS });
                } else {
                    res.send(500, { Token : "Error creating table"});
                }  
            });
        }
    };

    Xamarin app code for Table connection (Calling TestDataConnection()):

    public async Task<bool> TestDataConnection()
    {
        if( tableClient == null ) {
            await ConnectToDatabase();
        }
        CloudTable table = tableClient.GetTableReference("MeasurementJournal");
        bool exists = false;
        try {
            exists = await table.ExistsAsync();
        } catch (Exception e) {
            Debug.WriteLine("Error checking if table exists: " + e.ToString());
        }
        return exists;
    }
    
    private async Task<bool> ConnectToDatabase()
    {
        // Get credentials
        var credentials = await GetStorageCredentials();
    
        // Create client
        tableClient = new CloudTableClient(new Uri(Utility.ProjectConstants.tableServiceUrl), credentials);
    
        return true;
    }
    
    /**
     * GetStorageCredentials
     * 
     * Gets storage credentials from sas custom API
     */
    private async Task<StorageCredentials> GetStorageCredentials()
    {
        string token = "NULL";
    
        try {
            MobileServiceClient serviceClient = new MobileServiceClient(ACCOUNT_URL);
    
            //create req
            Model.SasRequest req = new Model.SasRequest();
            req.Table = "MeasurementJournal";
               
            //send req
            Model.SasResponse response = await serviceClient.InvokeApiAsync<Model.SasRequest, Model.SasResponse>(API_EXTENSION, req, HttpMethod.Post, null);
                    
            //save token from response
            token = response.Token;
        } catch (Exception e) {
            Debug.WriteLine("Received exception: " + e.ToString());
        }
        return new StorageCredentials(token);
    }


    Error message:

    01-07 16:13:22.374 28311 28311 I mono-stdout: Error checking if table exists: Microsoft.WindowsAzure.Storage.WrappedStorageException (0x80041193): <?xml version="1.0" encoding="utf-16"?>
    01-07 16:13:22.374 28311 28311 I mono-stdout: <!--An exception has occurred. For more information please deserialize this message via RequestResult.TranslateFromExceptionMessage.-->
    01-07 16:13:22.374 28311 28311 I mono-stdout: <RequestResult>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <HTTPStatusCode>403</HTTPStatusCode>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <HttpStatusMessage>Forbidden</HttpStatusMessage>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <TargetLocation>Primary</TargetLocation>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <ServiceRequestID>f90ae37f-0002-0030-1d33-693dbe000000</ServiceRequestID>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <ContentMd5 />
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <Etag />
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <RequestDate>Sat, 07 Jan 2017 16:13:22 GMT</RequestDate>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <StartTime>Sat, 07 Jan 2017 22:13:21 GMT</StartTime>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <EndTime>Sat, 07 Jan 2017 22:13:22 GMT</EndTime>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <Error>
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <Code>AuthorizationFailure</Code>
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <Message>This request is not authorized to perform this operation.
    01-07 16:13:22.374 28311 28311 I mono-stdout: RequestId:f90ae37f-0002-0030-1d33-693dbe000000
    01-07 16:13:22.374 28311 28311 I mono-stdout: Time:2017-01-07T22:13:22.5850271Z</Message>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   </Error>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   <ExceptionInfo>
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <Type />
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <HResult>-2146233088</HResult>
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <Message>Unexpected response code, Expected:OK or NotFound, Received:Forbidden</Message>
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <Source>Microsoft.WindowsAzure.Storage</Source>
    01-07 16:13:22.374 28311 28311 I mono-stdout:     <StackTrace>  at Microsoft.WindowsAzure.Storage.Core.Executor.Executor+&lt;ExecuteAsyncInternal&gt;d__6`1[T].MoveNext () [0x0095a] in &lt;b3bed838f8344d41a1a82c4a3b228bac&gt;:0 </StackTrace>
    01-07 16:13:22.374 28311 28311 I mono-stdout:   </ExceptionInfo>
    01-07 16:13:22.374 28311 28311 I mono-stdout: </RequestResult> ---> Microsoft.WindowsAzure.Storage.StorageException: Unexpected response code, Expected:OK or NotFound, Received:Forbidden
    01-07 16:13:22.374 28311 28311 I mono-stdout:   at Microsoft.WindowsAzure.Storage.Core.Executor.Executor+<ExecuteAsyncInternal>d__6`1[T].MoveNext () [0x0095a] in <b3bed838f8344d41a1a82c4a3b228bac>:0
    01-07 16:13:22.374 28311 28311 I mono-stdout: Request Information
    01-07 16:13:22.374 28311 28311 I mono-stdout: RequestID:f90ae37f-0002-0030-1d33-693dbe000000
    01-07 16:13:22.374 28311 28311 I mono-stdout: RequestDate:Sat, 07 Jan 2017 16:13:22 GMT
    01-07 16:13:22.374 28311 28311 I mono-stdout: StatusMessage:Forbidden
    01-07 16:13:22.374 28311 28311 I mono-stdout: ErrorCode:AuthorizationFailure


    Saturday, January 7, 2017 10:35 PM

Answers

  • Greetings Dan,

    I checked this a little further and found that Service SAS actually does not support CloudTable.ExistsAsync. You should either use Account SAS or not rely on ExistsAsync.
    Hope this helps!

    Regards.
    Md. Shihab

    **********************************************************************

    Please remember to click "Mark as Answer" on the post that helps you as this can be beneficial to other community members reading the thread. And vote as helpful.

    • Marked as answer by dbarton91 Friday, January 20, 2017 11:15 PM
    Thursday, January 19, 2017 8:57 AM

All replies

  • Hi,


    Thank you for contacting Microsoft forums. We are pleased to answer your query.

     

    We are checking on the query and will get back to you soon on this.

    I apologise for the inconvenience and appreciate your time and patience in this matter.
     

    Regards

    Md. Shihab

    Sunday, January 8, 2017 10:25 AM
  • Hi Shihab,

    Do you have any update on the status of your investigation?

    Thanks!

    Dan

    Thursday, January 12, 2017 4:06 AM
  • Hi Dan,

    Apologies for the delay in response.

    I'm still checking and will get back to you soon on this.


    Regards.

    Md. Shihab

    Thursday, January 12, 2017 6:35 AM
  • Hi Dan,

    This issue requires a further deeper dive technically so I recommend you 
    create a technical support ticket. The ticket enables you to work closely with the support engineers and get a quick resolution for your issue. 


    Regards.

    Md. Shihab

    Sunday, January 15, 2017 6:11 AM
  • Hi Shihab,

    Thanks for your reply! Can I create a technical support ticket without having an Azure support plan?

    Also, is it possible that a timestamp issue is causing the forbidden failure? I see that the request date in the error code says that it's 16:13 GMT, but the startdate says 22:13 GMT

    Monday, January 16, 2017 8:14 PM
  • Hi Dan,


    No, you’ll need an Azure paid support plan to receive one-on-one technical support.

    In the documentation on using SAS, here’s what I found about setting start time for SAS. This could be related to your error.

    Be careful with SAS start time. If you set the start time for a SAS to now, then due to clock skew (differences in current time according to different machines), failures may be observed intermittently for the first few minutes. In general, set the start time to be at least 15 minutes ago, or don't set it at all, which will make it valid immediately in all cases. The same generally applies to expiry time as well - remember that you may observe up to 15 minutes of clock skew in either direction on any request. Note for clients using a REST version prior to 2012-02-12, the maximum duration for a SAS that does not reference a stored access policy is 1 hour, and any policies specifying longer term than that will fail.


    Hope this helps!

    Regards.

    Md. Shihab

    **********************************************************************

    Please remember to click "Mark as Answer" on the post that helps you as this can be beneficial to other community members reading the thread. And vote as helpful.

    Tuesday, January 17, 2017 6:31 AM
  • Greetings Dan,

    I checked this a little further and found that Service SAS actually does not support CloudTable.ExistsAsync. You should either use Account SAS or not rely on ExistsAsync.
    Hope this helps!

    Regards.
    Md. Shihab

    **********************************************************************

    Please remember to click "Mark as Answer" on the post that helps you as this can be beneficial to other community members reading the thread. And vote as helpful.

    • Marked as answer by dbarton91 Friday, January 20, 2017 11:15 PM
    Thursday, January 19, 2017 8:57 AM