具有共享访问签名的查询Azure表未实现,但连接字符串有效

Ste*_*Lee 5 azure azure-table-storage

花几个小时试图解决这个问题.

我有一个表,想要创建一个只读SAS并给客户端组件读取访问权限.但永远不会成功.

如果只是直接使用连接字符串和挂钩表,如下所示:

    CloudStorageAccount storageAccount = CloudStorageAccount.Parse(SliStorageConnection);

    // Create the table client.
    CloudTableClient tableClient = storageAccount.CreateCloudTableClient();

    var table = tableClient.GetTableReference(GlobalFilterTable);

    TableOperation tableOperation = TableOperation.Retrieve<TableEntity>(FilterTablePartition, "filter1");
    TableResult tableResult = table.Execute(tableOperation);
Run Code Online (Sandbox Code Playgroud)

它工作正常.但是如下面的SAS,总是返回501 Not Implemented

    var policy = new SharedAccessTablePolicy
    {
        SharedAccessExpiryTime = DateTime.Now.AddMinutes(30),
        Permissions = SharedAccessTablePermissions.Query
    };

    string sas = table.GetSharedAccessSignature(
        policy,
        null,
        FilterTablePartition,
        String.Empty,
        FilterTablePartition,
        String.Empty);

    Uri tableSasUri = new Uri(table.Uri, sas);
    AccessTable(tableSasUri.AbsoluteUri.ToString());

private static void AccessTable(string tableSas)
{
    string filterTableBaseUrl = tableSas.Substring(0, tableSas.IndexOf('?'));

    var filterTableSasCredentials = new StorageCredentials(tableSas.Substring(filterTableBaseUrl.Length));
    CloudTableClient tableClient = new CloudTableClient(new Uri(filterTableBaseUrl), filterTableSasCredentials);

    var _manifestFilterCloudTable = tableClient.GetTableReference(GlobalFilterTable);

    TableOperation tableOperation = TableOperation.Retrieve<TableEntity>(FilterTablePartition, "filter1");
    TableResult tableResult = _manifestFilterCloudTable.Execute(tableOperation);
}
Run Code Online (Sandbox Code Playgroud)

尝试不同的方式,给出不到1小时的时间,命名或匿名策略标识符,仅使用签名("sig")来创建StorageCredentials.所有失败都有不同的错误.大多数情况下501 not implemented,有时候resource not found,有时候403 Forbidden.

无法在线查找有用的信息.我使用的是Microsoft.WindowsAzure.Storage3.1版SDK.

任何帮助都非常感谢

Gau*_*tri 4

我认为问题出在以下两行代码中:

CloudTableClient tableClient = new CloudTableClient(new Uri(filterTableBaseUrl), filterTableSasCredentials);

    var _manifestFilterCloudTable = tableClient.GetTableReference(GlobalFilterTable);
Run Code Online (Sandbox Code Playgroud)

基本上发生的情况是表名称在 中的表 URL 中重复两次manifestFilterCloudTable。创建 时CloudTableClient,URI 不应包含表名称。它应该只是类似的东西https://[youraccountname].table.core.windows.net

请在您的方法中使用以下代码AccessTable

        string filterTableBaseUrl = tableSas.Substring(0, tableSas.IndexOf('?'));
        var filterTableSasCredentials = new StorageCredentials(tableSas.Substring(filterTableBaseUrl.Length));
        filterTableBaseUrl = filterTableBaseUrl.Substring(0, filterTableBaseUrl.LastIndexOf("/"));
        tableClient = new CloudTableClient(new Uri(filterTableBaseUrl), filterTableSasCredentials);

        var _manifestFilterCloudTable = tableClient.GetTableReference("Address");

        TableOperation tableOperation = TableOperation.Retrieve<TableEntity>(FilterTablePartition, "filter1");
        TableResult tableResult = _manifestFilterCloudTable.Execute(tableOperation);
Run Code Online (Sandbox Code Playgroud)

我注意到的另一件事是,对于 SharedAccessPolicy,您正在使用DateTime.Now. 根据执行代码的时区,您可能会遇到 403 错误,因为 Azure 中的日期/时间采用 UTC。请改用DateTime.UtcNow