Reputation: 419
The following code throws an exception at the last line:
// Create a BlobServiceClient object which will be used to create a container client
System.out.println(String.format("Connection String %s", connectStr));
blobServiceClient = new BlobServiceClientBuilder().connectionString(connectStr).buildClient();
// Get a user delegation key for the Blob service that's valid for seven days.
// You can use the key to generate any number of shared access signatures over the lifetime of the key.
keyStart = OffsetDateTime.now();
keyExpiry = OffsetDateTime.now().plusHours(7);
error -> userDelegationKey = blobServiceClient.getUserDelegationKey(keyStart, keyExpiry);
Exception:
</Message><AuthenticationErrorDetail>Only authentication scheme Bearer is supported</AuthenticationErrorDetail></Error>"
Caused by: com.azure.storage.blob.models.BlobStorageException: Status code 403, "<?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:d375b3bf-b01e-0044-1191-9c75a8000000
I tried to adapt the .NET tutorial to Java but no luck so far.
It seems this error is related towards REST API calls, any ideas?
Upvotes: 1
Views: 2776
Reputation: 419
So after many attempts, to use User Delegation Keys using the Connection String of the storage account does not work. I had to register an app and add new app environment variables. Finally, check for the right Persmission in the IAM dashboard.
In my case I'm using Azure with Spring,
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-storage-blob</artifactId>
<version>12.8.0</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.1.2</version>
</dependency>
export AZURE_CLIENT_ID="xxxxxxx"
launchctl setenv AZURE_CLIENT_ID $AZURE_CLIENT_ID
export AZURE_TENANT_ID="xxxxxxx"
launchctl setenv AZURE_TENANT_ID $AZURE_TENANT_ID
export AZURE_CLIENT_SECRET="xxxxxxx"
launchctl setenv AZURE_CLIENT_SECRET $AZURE_CLIENT_SECRET
add correct role assignments of Storage Blob Data Contributor
to the user and app for the storage account. see this
Now can use following code for generating user delegation key and an example container SAS:
String endpoint = String.format(Locale.ROOT, "https://%s.blob.core.windows.net", "accountName");
// Create a BlobServiceClient object which will be used to create a container client
blobServiceClient = new BlobServiceClientBuilder().endpoint(endpoint)
.credential(new DefaultAzureCredentialBuilder().build()).buildClient();
// Get a user delegation key for the Blob service that's valid for seven days.
// You can use the key to generate any number of shared access signatures over the lifetime of the key.
keyStart = OffsetDateTime.now();
keyExpiry = OffsetDateTime.now().plusDays(7);
userDelegationKey = blobServiceClient.getUserDelegationKey(keyStart, keyExpiry);
BlobContainerSasPermission blobContainerSas = new BlobContainerSasPermission();
blobContainerSas.setReadPermission(true);
BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(keyExpiry,
blobContainerSas);
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient("containerName");
if (!blobContainerClient.exists())
blobContainerClient.create();
String sas = blobContainerClient
.generateUserDelegationSas(blobServiceSasSignatureValues, userDelegationKey);
Hope this helps anyone else!
Upvotes: 3