Azure / azure-storage-java

Microsoft Azure Storage Library for Java
https://docs.microsoft.com/en-us/java/api/overview/azure/storage
MIT License
189 stars 165 forks source link

Generating SAS token and presigned_url for uploading files from client end #583

Open ghost opened 1 year ago

ghost commented 1 year ago

Which service(blob, file, queue, table) does this issue concern?

Service: blob

Which version of the SDK was used?

        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-storage-blob</artifactId>
            <version>12.20.3</version>
        </dependency>

What problem was encountered?

I am trying to generate a SAS token and create a presigned_url to send back to my client so that client can upload files(image/pdf etc) using the presigned_url, much like AWS S3.

Here is the code I am wrote:

    @Override
    public void getMediaUploadCred(GetMediaUploadCredRequest request, StreamObserver<GetMediaUploadCredResponse> response) {
        BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(STORAGE_ACCOUNT_CONNECTION_STRING).buildClient();
        BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(CONTAINER_NAME);
        BlobSasPermission permission = new BlobSasPermission().setReadPermission(true).setWritePermission(true);
        OffsetDateTime expiryTime = OffsetDateTime.now().plusMinutes(30);

        String blobName = containerClient.getBlobClient(request.getFileName()).getBlobName();
        String sasToken = generateSasToken(STORAGE_ACCOUNT_NAME, STORAGE_ACCOUNT_KEY, CONTAINER_NAME, blobName, permission, expiryTime);
        log.info(sasToken);
        String url = String.format("https://%s.blob.core.windows.net/%s/%s?%s", STORAGE_ACCOUNT_NAME, CONTAINER_NAME, request.getFileName(), sasToken);
        GetMediaUploadCredResponse res = GetMediaUploadCredResponse.newBuilder()
                .setMediaId(blobName)
                .setUploadCredentialUrl(url)
                .build();
        response.onNext(res);
        response.onCompleted();
    }

And the CURL command I'm trying is:

 curl -X PUT "https://<Account-Name>.blob.core.windows.net/<Container-Name>/<file-name>?sv=2020-12-06&st=2023-03-29T11:18:51.752+06:00&se=2023-03-29T11:48:51.750354+06:00&sr=b&sp=rw&sig=7bTkhsT6JqIlaIU7MXsFpoTJgfnuvvU5cGBhgA35i3Y%3D" \
-H "Authorization: SharedAccessSignature sv=2020-12-06&st=2023-03-29T00:12:29.996111+06:00&se=2023-03-29T00:42:29.987109+06:00&sr=b&sp=rw&sig=%2BoC2ujMAeV7b9QkDkKsY75oBG9o5kvd8UZ4EZre2Q6A%3D" \
-H "Content-Type: image/jpeg" \
-T ~/Downloads/gfx100s_sample_04_thum-1.jpg

But I keep getting the following error:

<?xml version="1.0" encoding="utf-8"?>
<Error><Code>AuthenticationFailed</Code><Message>Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.
RequestId:ae59d9d5-401e-0013-0afe-619f18000000
Time:2023-03-29T05:19:20.5884736Z</Message></Error>%

Have you found a mitigation/solution?