我正在尝试使用SAS密钥以Java代码从Azure WASB检索容器。这是在HDFS代码中完成的,但是由于任何原因,我似乎都无法使其正常工作。我设法将其简化为下面的应用程序,该应用程序也不起作用。我认为这可能与我们如何生成SAS令牌有关,还是与Azure帐户的权限有关。有人可以看一下这个问题,并向我指出正确的方向吗?谢谢!
{{1}}
答案 0 :(得分:1)
根据您的代码,我认为您想通过使用SAS为容器构建URL来获取Blob容器的属性和元数据。但是,SharedAccessBlobPolicy
生成的SAS字符串类似于blob(sig=1G7tiQnLEtbjk2RSNuUSKH7gLNVZjqhuLQL%2Fci%2FXS50%3D&st=2017-01-30T16%3A00%3A00Z&se=2021-01-30T16%3A00%3A00Z&sv=2018-03-28&sp=racwdl&sr=b
)的sr=b
,而不是容器(sr=c
,例如从Azure存储复制的st=2019-01-31T08%3A38%3A46Z&se=2019-02-01T08%3A38%3A46Z&sp=rl&sv=2018-03-28&sr=c&sig=KnynNYBUtzNSYtBEcYakMrhAXPRIk60wztB3BFv5b%2Bs%3D
的{{1}}浏览器)。
我尝试通过以下代码将CloudStorageAccount
与SharedAccessAccountPolicy
结合使用,以为斑点生成Account SAS,但仍然无法正常工作。
帐户SAS 。帐户SAS委派对一项或多项存储服务中的资源的访问。通过服务SAS可用的所有操作也可以通过帐户SAS进行。此外,使用帐户SAS,您可以委派对适用于给定服务的操作的访问权限,例如“获取/设置服务属性”和“获取服务状态”。您还可以委派对服务SAS不允许的Blob容器,表,队列和文件共享的读取,写入和删除操作的访问权限。有关构建帐户SAS令牌的详细信息,请参阅构建帐户SAS。
SharedAccessAccountPolicy accountPolicy = new SharedAccessAccountPolicy();
accountPolicy.setPermissions(EnumSet.allOf(SharedAccessAccountPermissions.class));
accountPolicy.setSharedAccessStartTime(Date.valueOf(LocalDate.now().minusYears(2)));
accountPolicy.setSharedAccessExpiryTime(Date.valueOf(LocalDate.now().plusYears(2)));
String sas = csa.generateSharedAccessSignature(accountPolicy);
我测试以下代码,
StorageCredentials credentials = new StorageCredentialsSharedAccessSignature(sas);
CloudBlobContainer sasContainer = new CloudBlobContainer(new URI(container2.getUri().toString()+"?"+sas), credentials);
sasContainer.downloadAttributes();
然后获取异常。
Exception in thread "main" java.lang.IllegalArgumentException: Cannot provide credentials as part of the address and as constructor parameter. Either pass in the address or use a different constructor.
或者测试代码CloudBlobContainer sasContainer = new CloudBlobContainer(new URI(container2.getUri().toString()+"?"+sas))
以获取异常。
Exception in thread "main" com.microsoft.azure.storage.StorageException: Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
这似乎是由我在研究SDK源代码后实施Azure Java Storage SDK v8.0.0
引起的。也许您可以向Microsoft报告此问题。
我尝试通过以下代码使用Azure Java Storage SDK v10
使用SAS生成容器URL,它工作正常。
v10
的Maven依赖项:
<!-- https://mvnrepository.com/artifact/com.microsoft.azure/azure-storage-blob -->
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>10.4.0</version>
</dependency>
使用SAS生成容器网址的代码:
String accountName = "<your account name>";
String accountKey = "<your account key>";
SharedKeyCredentials credentials = new SharedKeyCredentials(accountName, accountKey);
final ServiceURL serviceURL = new ServiceURL(new URL("http://" + accountName + ".blob.core.windows.net"), StorageURL.createPipeline(credentials, new PipelineOptions()));
String containerName = "<container name>";
ServiceSASSignatureValues values = new ServiceSASSignatureValues()
.withProtocol(SASProtocol.HTTPS_ONLY) // Users MUST use HTTPS (not HTTP).
.withExpiryTime(OffsetDateTime.now().plusDays(2)) // 2 days before expiration.
.withContainerName(containerName)
.withBlobName(blobName);
ContainerSASPermission permission = new ContainerSASPermission()
.withRead(true)
.withAdd(true)
.withWrite(true);
values.withPermissions(permission.toString());
SASQueryParameters serviceParams = values.generateSASQueryParameters(credentials);
String sas = serviceParams.encode();
String containerUrlWithSAS = String.format(Locale.ROOT, "https://%s.blob.core.windows.net/%s%s",
accountName, containerName, sas);
HttpPipeline pipeline = new HttpPipelineBuilder().build();
ContainerURL sasContainer = new ContainerURL(new URL(containerUrlWithSAS), pipeline);
sasContainer.getProperties();
注意:SDK getProperties
中ContainerURL
的功能v10
与SDK downloadAttributes
中CloudBlobContainer
的{{1}}相似,该函数也返回容器的元数据和系统属性。