Azure 表和容器的共享访问策略





5.00/5 (2投票s)
设置和使用存储表格和容器的共享访问策略,为您的 Azure 凭据提供额外的安全层。
引言
我希望在我的 ASP.NET 网站的代码隐藏中执行 Azure 表格和 Blob 的 CRUD 事务,但我希望为我的 Azure 凭据添加一个额外的安全层。然后,随着我的 Azure 存储帐户增长到数十个,每个帐户都有数十个表格和容器,轻松高效地跟踪存储访问策略的需求成为一个优先事项。我想要一个仪表板 - 我希望用 WPF 制作它,并完全用 C# 完成 - 没有 xml,没有 http。我想分享一些我在这个过程中学到的东西,并将所有内容放在一起。
要求
您需要在您的项目中添加对 Azure Storage 的引用。在 Visual Studio 中,右键单击您的项目,然后转到 管理 NuGet 程序包… 查找并安装 WindowsAzure.Storage
您将需要添加以下部分或全部内容,具体取决于您正在做什么。
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Auth;
获取存储帐户
string storageAccountName = "yourStorageAccountName";
string key = "eitherYourPrimaryOrSecondaryKey";
string connection =
String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
storageAccountName, key);
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connection);
创建表格策略
CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); //if you need to see a list of tables in this storage account... IEnumerable<CloudTable> tables = tableClient.ListTables(); CloudTable table = tableClient.GetTableReference("yourTableName"); SharedAccessTablePolicies permissions = table.GetPermissions().SharedAccessPolicies;
可以在任何一个表格或容器上设置的策略限制为 5 个。如果您已经有 5 个,则尝试设置另一个将失败。像这样清除它们
permissions.SharedAccessPolicies.Clear();
SharedAccessTablePolicies
实际上是 KeyValuePair<string, SharedAccessTablePolicy>
类型的集合,键是策略的名称,值是实际的策略 - 您可以像这样制作一个
SharedAccessTablePolicy newPolicy = new SharedAccessTablePolicy();
您必须为策略设置一个到期日期/时间 - 建议您不要设置少于 15 分钟的时间,以允许服务器时钟之间可能存在差异。
newPolicy.SharedAccessExpiryTime = DateTime.UtcNow.AddYears(1);
您可以选择设置开始时间 - 如果您没有指定 policy.SharedAccessStartTime
,则该策略将立即生效。您可以一次性添加所有权限,如下所示
newPolicy.Permissions = SharedAccessTablePermissions.Query | SharedAccessTablePermissions.Add | SharedAccessTablePermissions.Update | SharedAccessTablePermissions.Delete;
或者一次添加一个,如下所示
newPolicy.Permissions |= SharedAccessTablePermissions.Query; newPolicy.Permissions |= SharedAccessTablePermissions.Add; newPolicy.Permissions |= SharedAccessTablePermissions.Update; newPolicy.Permissions |= SharedAccessTablePermissions.Delete;
完成后,您将返回一个新的
KeyValuePair<string, SharedAccessTablePolicy>( "yourNewPolicyName", newPolicy);
将您的新策略添加到现有的权限集中(假设现有策略少于 5 个)
permissions.SharedAccessPolicies.Add(newPolicy.Key, newPolicy.Value);
完成策略制定后,像这样设置它们
table.SetPermissions(permissions);
您的新策略生成一个 SharedAccessSignature - 看起来像这样
"?sv=2015-04-05&tn= yourTableName &sig=bb%2SjxB0Q1eFnBAJ71KhU0IjzqW2YeeqvSG8cx%2BlHkpo%3D&se=2017-11-19T20%3A03%3A03Z&sp=raud";
sv=2015-04-05
是用于创建策略的服务器版本。
此策略写入的表名
tn= yourTableName
签名本身
sig=bb%2SjxB0Q1eFnBAJ71KhU0IjzqW2YeeqvSG8cx%2BlHkpo%3D
接下来是到期日期
se=2017-11-19T20%3A03%3A03Z
然后是允许的权限
sp=raud
此选项允许读取、添加(写入)、更新和删除
因此,总而言之,假设我们要覆盖所有现有策略并制定三个单独的策略,一个读取,一个写入,一个更新,所有这些策略的到期日期都是未来 2 年。我将使用表格名称和它授予的权限来命名每个策略。
void SetReadWriteUpdate(string tableName)
{
string storageAccountName = "yourStorageAccountName";
string key = "eitherYourPrimaryOrSecondaryKey";
string connection =
String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
storageAccountName, key);
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connection);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference(tableName);
SharedAccessTablePolicies permissions = table.GetPermissions().SharedAccessPolicies;
permissions.SharedAccessPolicies.Clear();
SharedAccessTablePolicy policyRead = new SharedAccessTablePolicy();
policyRead.SharedAccessExpiryTime = DateTime.UtcNow.AddYears(2);
policyRead.Permissions = SharedAccessTablePermissions.Query;
permissions.SharedAccessPolicies.Add(new KeyValuePair<string,
SharedAccessTablePolicy>(tableName + "Read", policyRead));
SharedAccessTablePolicy policyWrite = new SharedAccessTablePolicy();
policyWrite.SharedAccessExpiryTime = DateTime.UtcNow.AddYears(2);
policyWrite.Permissions = SharedAccessTablePermissions.Add;
permissions.SharedAccessPolicies.Add(new KeyValuePair<string,
SharedAccessTablePolicy>(tableName + "Write", policyWrite));
SharedAccessTablePolicy policyUpdate = new SharedAccessTablePolicy();
policyUpdate.SharedAccessExpiryTime = DateTime.UtcNow.AddYears(2);
policyUpdate.Permissions = SharedAccessTablePermissions.Update;
permissions.SharedAccessPolicies.Add(new KeyValuePair<string,
SharedAccessTablePolicy>(tableName + "Update", policyUpdate));
table.SetPermissions(permissions);
}
编辑单个表格策略
如果您只想更新单个策略,则需要先将其从现有的策略集中删除,制定一个新的策略,然后将其添加回策略集合中,并将其设置回表格。
SharedAccessTablePolicies permissions = table.GetPermissions().SharedAccessPolicies;
permissions.SharedAccessPolicies.Remove("theNameOfThePolicyToRemove");
SharedAccessTablePolicy newPolicy = new SharedAccessTablePolicy();
//set new policy stuff
permissions.SharedAccessPolicies.Add(new KeyValuePair<string,
SharedAccessTablePolicy>("newPolicyName", newPolicy));
table.SetPermissions(permissions);
创建容器策略
在容器上设置策略基本上是相同的,但将术语 Blob 替换为您找到 Table 的地方。但这有点令人困惑,因为您是在容器上设置策略,而不是像名称所暗示的那样在 blob 上设置策略。另一个区别是容器权限允许列出,但不允许更新 - 它是一个容器,您无法更新容器本身。列出允许列出容器中包含的 blob - 您可以使用与上面列出表格相同的方式进行操作。
void SetPermissionsContainer(string yourContainerName)
{
string storageAccountName = "yourStorageAccountName";
string key = "eitherYourPrimaryOrSecondaryKey";
string connection =
String.Format("DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
storageAccountName, key);
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connection);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(yourContainerName);
BlobContainerPermissions permissions = container.GetPermissions().SharedAccessPolicies;
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
policy.SharedAccessExpiryTime = DateTime.UtcNow.AddYears(2);
policy.Permissions |= SharedAccessBlobPermissions.Read;
policy.Permissions |= SharedAccessBlobPermissions.Write;
policy.Permissions |= SharedAccessBlobPermissions.Delete;
policy.Permissions |= SharedAccessBlobPermissions.List;
permissions.SharedAccessPolicies.Add(policy.Key, policy.Value);
table.SetPermissions(permissions);
}
获取签名
现在您有了存储的访问策略,您该怎么做?您需要知道它写入的表格(或容器)和策略名称。
string GetSignature(CloudTable table, string policyName)
{
SharedAccessTablePolicies policies = table.GetPermissions().SharedAccessPolicies;
SharedAccessTablePolicy policy = policies[policyName];
return table.GetSharedAccessSignature(policy);
}
现在您可以在您的应用程序中使用该签名,或者将其提供给另一个人使用,您的 Azure 凭据将保持机密。要使用它,您需要签名本身、存储帐户名称和表格名称。
使用签名
void UseMyNewPolicy(string signature, string accountName, string tableName)
{
StorageCredentials creds = new StorageCredentials(signature);
string endpoint = string.Format("https://{0}.table.core.windows.net", accountName);
CloudTableClient client = new CloudTableClient(new Uri(endpoint), creds);
CloudTable table = client.GetTableReference(tableName);
}
现在用户可以对表格执行允许的任何操作。
这是完成的仪表板的截图
附加资源
- http://justazure.com/azure-blob-storage-part-9-shared-access-signatures/
- https://azure.microsoft.com/en-us/documentation/articles/storage-manage-access-to-resources/
- https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-shared-access-signature-part-1/
- 了解表格服务数据模型
- 使用 Azure 表格存储