使用共享访问签名 returns 查询 Azure Table 未实现,但连接字符串有效
Query Azure Table with Shared Access Signature returns not implemented, but with connection string works
花很多时间尝试解决这个问题。
我有一个 table 并想创建一个只读 SAS 并授予客户端组件读取权限。但永远不会成功。
如果只是使用连接字符串并像这样直接连接table:
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);
它工作正常。但是像下面这样的 SAS,总是 returns 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);
}
尝试了不同的方式,给不到 1 小时的时间,命名或匿名策略标识符,仅使用签名 ("sig") 创建 StorageCredentials
。都因不同的错误而失败。大多数 501 not implemented
,有时 resource not found
,有时 403 Forbidden
。
无法在线找到有用的信息。我正在使用 Microsoft.WindowsAzure.Storage
版本 3.1 SDK。
非常感谢任何帮助
我认为问题出在以下两行代码中:
CloudTableClient tableClient = new CloudTableClient(new Uri(filterTableBaseUrl), filterTableSasCredentials);
var _manifestFilterCloudTable = tableClient.GetTableReference(GlobalFilterTable);
基本上发生的事情是 table 名称在 table URL 中重复了两次 manifestFilterCloudTable
。创建 CloudTableClient
时,URI 不应包含 table 名称。它应该只是类似于 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);
另一件事我注意到,对于 SharedAccessPolicy,您使用的是 DateTime.Now
。根据执行代码的时区,您可能 运行 出现 403 错误,因为 Azure 中的 date/time 是 UTC。请改用DateTime.UtcNow
。
花很多时间尝试解决这个问题。
我有一个 table 并想创建一个只读 SAS 并授予客户端组件读取权限。但永远不会成功。
如果只是使用连接字符串并像这样直接连接table:
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);
它工作正常。但是像下面这样的 SAS,总是 returns 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);
}
尝试了不同的方式,给不到 1 小时的时间,命名或匿名策略标识符,仅使用签名 ("sig") 创建 StorageCredentials
。都因不同的错误而失败。大多数 501 not implemented
,有时 resource not found
,有时 403 Forbidden
。
无法在线找到有用的信息。我正在使用 Microsoft.WindowsAzure.Storage
版本 3.1 SDK。
非常感谢任何帮助
我认为问题出在以下两行代码中:
CloudTableClient tableClient = new CloudTableClient(new Uri(filterTableBaseUrl), filterTableSasCredentials);
var _manifestFilterCloudTable = tableClient.GetTableReference(GlobalFilterTable);
基本上发生的事情是 table 名称在 table URL 中重复了两次 manifestFilterCloudTable
。创建 CloudTableClient
时,URI 不应包含 table 名称。它应该只是类似于 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);
另一件事我注意到,对于 SharedAccessPolicy,您使用的是 DateTime.Now
。根据执行代码的时区,您可能 运行 出现 403 错误,因为 Azure 中的 date/time 是 UTC。请改用DateTime.UtcNow
。