Как создать токен SAS для Azure из Java с той же структурой, что и токен, созданный на портале Azure?

Я пытаюсь загрузить файл в контейнер Azure из базового приложения Spring Boot, и пока мне это удалось. Однако когда я пытаюсь прочитать или записать теги в большом двоичном объекте Azure, я постоянно получаю следующую ошибку, из-за которой мне кажется, что мне не хватает авторизации на токене SAS.

com.azure.storage.blob.models.BlobStorageException: If you are using a StorageSharedKeyCredential, and the server returned an error message that says 'Signature did not match', you can compare the string to sign with the one generated by the SDK. To log the string to sign, pass in the context key value pair 'Azure-Storage-Log-String-To-Sign': true to the appropriate method call.
If you are using a SAS token, and the server returned an error message that says 'Signature did not match', you can compare the string to sign with the one generated by the SDK. To log the string to sign, pass in the context key value pair 'Azure-Storage-Log-String-To-Sign': true to the appropriate generateSas method call.
Please remember to disable 'Azure-Storage-Log-String-To-Sign' before going to production as this string can potentially contain PII.
Status code 403, "<?xml version = "1.0" encoding = "utf-8"?>
<Error><Code>AuthorizationPermissionMismatch</Code><Message>This request is not authorized to perform this operation using this permission.

Токен SAS генерируется следующим образом:

OffsetDateTime startTime = OffsetDateTime.now().minusMinutes(1);
OffsetDateTime expiryTime = startTime.plusHours(10);
UserDelegationKey userDelegationKey = blobServiceClient.getUserDelegationKey(startTime, expiryTime);

BlobSasPermission sasPermission = new BlobSasPermission()
    .setAddPermission(true)
    .setCreatePermission(true)
    .setDeletePermission(true)
    .setDeleteVersionPermission(true)
    .setExecutePermission(true)
    .setListPermission(true)
    .setMovePermission(true)
    .setPermanentDeletePermission(true)
    .setReadPermission(true)
    .setTagsPermission(true)
    .setWritePermission(true);

BlobServiceSasSignatureValues sasSignatureValues = new BlobServiceSasSignatureValues(expiryTime, sasPermission)
    .setStartTime(startTime);

BlobClient blobClient = blobContainerClient.getBlobClient("someBlob");
String sasToken = blobClient.generateUserDelegationSas(sasSignatureValues, userDelegationKey);

где blobServiceClient и blobContainerClient — два поля, автоматически добавляемые в мой класс обслуживания (application.yml моего приложения содержит spring.cloud.azure.storage.blob.container-name и spring.cloud.azure.storage.blob.endpoint).

У меня нет проблем при создании токена через портал Azure. Я вижу, что он имеет немного другую структуру и содержит раздел srt (соответствующий разрешенным типам ресурсов на портале), который я не могу сгенерировать из Java:

  • Сгенерировано с портала: sv=<VERSION>&ss=b&srt=o&sp=rwdlaciytfx&se=<EXPIRY TIME>&st=<START TIME>&spr=https&sig=<SIGNATURE>
  • Сгенерировано из Java: sv=<VERSION>&st=<START TIME>&se=<EXPIRY TIME>&skoid=<SOME ID>&sktid=<SOME OTHER ID>&skt=2024-08-30T10%3A43%3A42Z&ske=2024-08-30T10%3A45%3A42Z&sks=b&skv=2024-05-04&sr=b&sp=racwdxyltme&sig=<SIGNATURE>

Как я могу создать «хороший» токен SAS, который позволит мне читать и записывать теги в большом двоичном объекте Azure на Java?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как я могу создать «хороший» токен SAS, который позволит мне читать и записывать теги в большом двоичном объекте Azure на Java?

Вы можете создать токен SAS так же, как портал, с помощью MS-Document, используя Azure Java SDK.

Код:

    private final String accountName = "venkat326123";
    private final String accountKey = "Txxxx = ";
    private final StorageSharedKeyCredential credential;
    private final BlobServiceClient blobServiceClient;
    private final BlobClient blobClient;
    private final BlobClient sasBlobClient;

    public App() {
        credential = new StorageSharedKeyCredential(accountName, accountKey);

        blobServiceClient = new BlobServiceClientBuilder()
            .endpoint(String.format("https://%s.blob.core.windows.net/", accountName))
            .credential(credential)
            .buildClient();

        blobClient = blobServiceClient
            .getBlobContainerClient("test")
            .getBlobClient("example.csv");

        OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
        BlobSasPermission sasPermission = new BlobSasPermission()
            .setReadPermission(true)
            .setWritePermission(true)
            .setTagsPermission(true); 

        BlobServiceSasSignatureValues sasSignatureValues = new BlobServiceSasSignatureValues(expiryTime, sasPermission)
            .setStartTime(OffsetDateTime.now().minusMinutes(5));

        String sasToken = blobClient.generateSas(sasSignatureValues);
        System.out.println("Generated SAS Token: " + sasToken);

        sasBlobClient = new BlobClientBuilder()
            .endpoint(blobClient.getBlobUrl() + "?" + sasToken)
            .buildClient();
    }

    public void writeBlobTags() {
        Map<String, String> tags = new HashMap<>();
        tags.put("project", "quickstart");
        tags.put("env", "test");
        sasBlobClient.setTags(tags);
        System.out.println("Tags added to the blob.");
    }

    public void readBlobTags() {
        Map<String, String> tags = sasBlobClient.getTags();
        System.out.println("Blob tags: " + tags);
    }

    public static void main(String[] args) {
        App app = new App();  
        app.writeBlobTags();  // Write tags to the blob
        app.readBlobTags();   // Read tags from the blob
    }

Выход:

Generated SAS Token: sv=2023-11-03&st=2024-09-02T03%3A57%3A22Z&se=2024-09-03T04%3A02%3A22Z&sr=b&sp=rwt&sig=cwrK%2F2yuuHyxxxxxx
Tags added to the blob.
Blob tags: {project=quickstart, env=test}

Портал:

Другие вопросы по теме