В соответствии с вашим кодом, я думаю, вы хотите получить свойства и метаданные контейнера больших двоичных объектов, создав URL-адрес с помощью SAS для контейнера.Однако строка SAS, сгенерированная SharedAccessBlobPolicy
, похожа на 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
, например st=2019-01-31T08%3A38%3A46Z&se=2019-02-01T08%3A38%3A46Z&sp=rl&sv=2018-03-28&sr=c&sig=KnynNYBUtzNSYtBEcYakMrhAXPRIk60wztB3BFv5b%2Bs%3D
, скопированного из обозревателя хранилища Azure).
Iпытался использовать CloudStorageAccount
с SharedAccessAccountPolicy
для создания учетной записи SAS для блоба с помощью приведенного ниже кода, но он все еще не работает.
учетной записи SAS .Учетная запись SAS делегирует доступ к ресурсам в одной или нескольких службах хранения.Все операции, доступные через службу SAS, также доступны через учетную запись SAS.Кроме того, с помощью учетной записи SAS вы можете делегировать доступ к операциям, которые применяются к данной службе, например, «Получить / установить свойства службы» и «Получить статистику службы».Вы также можете делегировать доступ к операциям чтения, записи и удаления для контейнеров BLOB-объектов, таблиц, очередей и общих файловых ресурсов, которые не разрешены для службы SAS.См. Создание аккаунта 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.
Кажется, это вызвано реализацией Azure Java Storage SDK v8.0.0
после того, как я исследовалисходные коды SDK.Возможно, вы можете сообщить об этом Microsoft, чтобы попросить решить эту проблему.
Я попытался сгенерировать URL-адрес контейнера с помощью SAS, используя Azure Java Storage SDK v10
, с помощью приведенного ниже кода, он работает нормально.
Maven-зависимость для v10
:
<!-- 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>
Код для генерации URL-адреса контейнера с 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();
Примечание: функция getProperties
из ContainerURL
в SDK v10
аналогично downloadAttributes
из CloudBlobContainer
в SDK v8
, который также возвращает метаданные контейнера и системные свойства.