0

私はXamarinアプリケーションのSASトークンを生成するカスタムAPIをセットアップしました。アプリケーションでトークンを受け取ったら、テーブルに接続し、.ExistsAsync()を実行してテーブルと通信できることを確認します。私はSASを正しく生成した問題にぶち当たっていますが、開始時刻と終了時刻がオフになっているのかどうかは疑問ですが、ExistsAsync()を呼び出そうとするとAuthorization Failureが発生します。私のSAS生成API、ExamsAsync()を呼び出すXamarinアプリメソッド、および私が受け取っているエラーメッセージは以下の通りです。 SASの世代のためのXamarinのSAS経由でAzureテーブルにアクセスするときの認証エラー

カスタムAPI:(TestDataConnection()を呼び出す)表接続用

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アプリコード:

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); 
} 

エラーメッセージ:

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 
+0

CloudTable.ExistsAysnc()がクエリテーブルREST APIを呼び出しているため、QueryEntity権限を持つテーブルSASにはこの操作が許可されていません。メソッドを実行するには、アカウントキーまたはアカウントSASが必要です。 –

+0

おかげさまで@ ZhaoxingLu-Microsoft、私はazure-storage-netプロジェクトのバグを作成し、同じ答えを得ました。下の回答を追加した場合は、それを正しいとマークします – dbarton91

答えて

1

CloudTable.ExistsAysnc()Query Tables REST APIを呼び出して、そのQueryEntity権限を持つテーブルSASは、この操作のために許可されていません。 CloudTable.ExistsAysnc()メソッドを実行するには、アカウントキーまたはアカウントSASが必要です。

0

私はあなたを信じてライブラリの不具合を発見しました。私はこのエラーを再現することができます。 Githubで同じ問題を提出することをお勧めします。

一方、テーブルの存在を確認できるもう1つの方法は、テーブルを照会して1つのレコードをフェッチすることです。テーブルが空であるかレコードが含まれていても問題ありません。テーブルが存在しない場合は、404エラーが発生します。ここで

はそうするサンプルコードです:

 var cred = new StorageCredentials(accountName, accountKey); 
     var account = new CloudStorageAccount(cred, true); 
     var client = account.CreateCloudTableClient(); 
     var table = client.GetTableReference("Hello1"); 
     var sas = table.GetSharedAccessSignature(new SharedAccessTablePolicy() 
     { 
      Permissions = SharedAccessTablePermissions.Query, 
      SharedAccessExpiryTime = DateTime.UtcNow.AddDays(1), 
      SharedAccessStartTime = DateTime.UtcNow.AddDays(-1) 
     }); 
     var tableClient = new CloudTableClient(account.TableEndpoint, new StorageCredentials(sas)); 
     table = tableClient.GetTableReference("Hello1"); 
     var queryResult = table.ExecuteQuerySegmented(new TableQuery() 
     { 
      TakeCount = 1 
     }, null); 
+0

あなたのアドバイスを受け取り、GitHubに問題を提出しました。 ExistsAsync()はテーブル/サービスSASでサポートされていないことが分かります – dbarton91

関連する問題