我正在尝试设计在本地服务器上运行的Java应用程序,该服务器管理对存储在Windows Azure中的blob的访问权限。云存储资源由多个移动应用程序(也使用Java编写)使用,这些应用程序需要对云中托管的单个blob容器进行读取访问,有时还需要临时写入访问。我正在使用Windows Azure Plugin for Eclipse with Java by Microsoft Open Technologies。
我的问题是:Azure中的容器级stored access policies如何(或如果)在到期时恢复到先前存储的策略(READ),而不是“无法访问”。 “
MSDN文章:Creating a Shared Access Signature in Java提供了一个良好的开端,但它还没有说明如何使用容器级存储策略来使用Java管理共享访问策略。我正在学习Java和SAS,因为我无法找到类似于Access Control for Azure Blobs的Java代码示例,所以我在下面添加了一小段Java代码来演示我的问题。
服务器应用程序检索用于连接Azure存储的专用存储连接字符串。获取云存储帐户并创建云blob客户端。获取对容器的引用,并创建一个尚不存在的容器。 (请注意,容器名称必须为小写。)然后,它会下载容器的当前权限。 (可以为容器保存最多五个容器级存储的访问策略。)
例如,假设有两个存储的访问策略,名为“baxter”和“heath”,控制容器级权限,并且当存储的容器访问策略时,两个策略都设置为READ(仅)以前保存过。这些具有READ权限的初始策略将在几个月后过期。分配给“heath”或“baxter”策略的移动应用程序然后从对sascontainer6中存储的blob的读访问开始,通过uri字符串类似于:
http://grassy.blob.core.windows.net/sascontainer6/image4.jpg?sr=c&sv=2012-02-12&sig=5G7EOgiYYNEGmw2Y0T4IUgt%2FzTnmYpaxWfB5nEira08%3D&si=baxter
http://grassy.blob.core.windows.net/sascontainer6/image4.jpg?sr=c&sv=2012-02- 12&sig=llUoAg2PvFUfhO28ncrlheh2RRJdb7smQEX6nO8xoCk%3D&si=heath
根据需要,服务器应用程序可以将移动应用程序的子集提升为READ和WRITE权限,而无需发出新字符串。它可以通过修改随容器保存的“baxter”策略来实现。控件的“粒度”在策略级别,策略更新允许分配给“baxter”策略的所有移动应用程序在容器中写入(或覆盖)blob。分配给“heath”策略的移动应用程序继续具有READ(仅)权限。以类似的方式,服务器应用程序可以撤销对分配给特定策略的应用程序的容器的所有访问权。
在更改策略之前,服务器应用程序确保已关闭对容器的公共访问权限。它指定当前时间作为开始时间和访问的到期时间,即开始时间后一小时。它为新策略设置READ和WRITE权限。最后,现有的“baxter”政策被新政策所覆盖。
generateSharedAccessSignature方法可以获取“baxter”和“heath”策略的共享访问签名(SAS)。更改策略中保存的权限不应更改SAS,使用上述uri字符串的应用程序应在指定的到期时间之前工作。
但是,一旦达到到期时间,“baxter”字符串将失去对容器的所有权限,包括READ和WRITE。但这不是我想要发生的事情。我需要分配给“baxter”策略的移动应用程序的权限才能恢复为READ(仅限)。因为具有WRITE访问权限的SAS字符串使任何人都可以写入资源,所以最佳做法是保持开始时间和到期时间尽可能短,不超过一小时。对于我的特定应用程序,可以将权限设置为READ更长时间。
我的问题是:如何(或者如果)Azure中的容器级共享访问策略可用于允许令牌(即上面显示的“baxter”字符串)恢复为备用策略(即READ)而不是“没有访问权。”
public static void main(String[] args) throws InvalidKeyException, URISyntaxException, StorageException
{
Account creds = new Account();
final String storageConnectionString = creds.getstorageconnectionstring();
CloudStorageAccount storageAccount = CloudStorageAccount.parse(storageConnectionString);
CloudBlobClient blobClient = storageAccount.createCloudBlobClient();
CloudBlobContainer container = blobClient.getContainerReference("sascontainer6");
container.createIfNotExist();
BlobContainerPermissions containerPermissions = container.downloadPermissions();
containerPermissions.setPublicAccess(BlobContainerPublicAccessType.OFF);
SharedAccessBlobPolicy policy = new SharedAccessBlobPolicy();
GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
calendar.setTime(new Date());
policy.setSharedAccessStartTime(calendar.getTime());
calendar.add(Calendar.HOUR, 1);
policy.setSharedAccessExpiryTime(calendar.getTime());
policy.setPermissions(EnumSet.of(SharedAccessBlobPermissions.READ, SharedAccessBlobPermissions.WRITE));
containerPermissions.getSharedAccessPolicies().put("baxter", policy);
container.uploadPermissions(containerPermissions);
String sas = container.generateSharedAccessSignature(new SharedAccessBlobPolicy(),"baxter");
String sasex = container.generateSharedAccessSignature(new SharedAccessBlobPolicy(),"heath");
}
答案 0 :(得分:1)
您与SAS一起展示了对容器级访问策略的良好理解。所有解释都会导致非常具体的问题:
我的问题是:如何(或如果)容器级共享访问策略 Azure可用于允许令牌(即显示的“baxter”字符串) 以上)恢复到备用策略(即READ)而不是 “没有访问权。”
哪个'回答,不幸的是否。您无法为容器级别策略到期时发生的情况定义fallback
。一旦它到期,它就结束了,完成了。没有与之关联的SAS可以对相关资源执行任何操作。您必须从服务器端代码使用新权限和新的到期日期再次显式覆盖它。
但我想稍微挑战你的概念架构。你有一个声明:
根据需要,服务器应用程序可以提升移动设备的子集 应用程序同时具有READ和WRITE权限 发出一个新字符串。
即使您的server
这样做,移动客户如何理解现在他们也可以write
,而不仅仅是来自该云存储的read
?我真的怀疑你的移动客户端总是试图默默地写死,如果他们不能。
我的猜测是,在移动客户端意识到它可以写入云存储之前,存在某种server-to-mobile-client
通信。如果没有这样的沟通,那么恕我直言。
但是,如果存在此类通信,那么没有什么能阻止您提供具有RW
权限(读取和写入)的新的较短生存SAS。这个新的更短的生活SAS甚至可以是stand alone
SAS,这意味着它不与任何存储的访问策略相关联,并且是专门为写入blob而发布的。
我的另一个猜测是,您希望避免通过线路发送SAS以避免man-in-the-middle
类型攻击。而是希望在应用程序中预先配置SAS。如果是这种情况,我可以建议为读取和写入分别设置访问策略。您可以安全地使用expired
访问策略进行编写,并仅在需要时使其有效。您的设备现在将有4个SAS URI而不是2个,但它(设备)将准确知道哪个策略是只读的,并使用哪个可以尝试写入。请注意,即使过期,写入访问策略仍与容器关联,不会将其删除。因此,您只需在下次希望它处于活动状态时进行更新。