Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to programmatically generate Azure SaS token for Blob container even when the user is not authenticated with SaS token java

I am authenticating my user using ClientCredentails. My client does have the permission to generate SaS token. Now I want to generate SaS token from code for a short period of time so that the customer can directly download the file.

        String tenantId = "TenantId";
        String clientSecret = "XXXX"
        String clientId = "abc-123"

        String authorityUrl = AzureAuthorityHosts.AZURE_PUBLIC_CLOUD +  tenantId;

        ClientSecretCredential credential = new ClientSecretCredentialBuilder()
                .authorityHost(authorityUrl)
                .tenantId(tenantId)
                .clientSecret(clientSecret)
                .clientId(clientId)
                .build();


         BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
                    .credential(credential)
                    .endpoint(azureStorageEndPoint)
                    .buildClient(); 


        // Upload a file            
        BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(containerName);            
        BlobClient blobClient = blobContainerClient.getBlobClient("Test.txt");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("<FILE_PATH>")));
        blobClient.upload(bufferedInputStream, bufferedInputStream.available(),true);     


        BlobSasPermission blobSasPermission = new BlobSasPermission().setReadPermission(true);
        OffsetDateTime expiryTime = OffsetDateTime.now().plusDays(1);
        BlobServiceSasSignatureValues values = new BlobServiceSasSignatureValues(expiryTime, blobSasPermission)
                    .setStartTime(OffsetDateTime.now());

        String generateSas = blobClient.generateSas(values);



        Getting Error 

        java.lang.NullPointerException: The argument must not be null or an empty string. Argument name: storageSharedKeyCredentials.

Tried to find some azure docs which clearly says that "Client must be authenticated via StorageSharedKeyCredential"

https://learn.microsoft.com/en-us/java/api/com.azure.storage.blob.blobserviceclient.generateaccountsas?view=azure-java-stable

Question is how to generate StorageSharedKeyCredential programmatically if your code is authenticating with different ways.

like image 248
Raj Avatar asked Oct 29 '25 06:10

Raj


1 Answers

I finally found the answer, when we login with client credentials then we need to create UserDelegationKey and then use that key to get the SaS token

String tenantId = "TenantId";
        String clientSecret = "XXXX"
        String clientId = "abc-123"

        String authorityUrl = AzureAuthorityHosts.AZURE_PUBLIC_CLOUD +  tenantId;

        ClientSecretCredential credential = new ClientSecretCredentialBuilder()
                .authorityHost(authorityUrl)
                .tenantId(tenantId)
                .clientSecret(clientSecret)
                .clientId(clientId)
                .build();


         BlobServiceClient blobServiceClient = new BlobServiceClientBuilder()
                    .credential(credential)
                    .endpoint(azureStorageEndPoint)
                    .buildClient(); 


        // Upload a file            
        BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(containerName);            
        BlobClient blobClient = blobContainerClient.getBlobClient("Test.txt");
        BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(new File("<FILE_PATH>")));
        blobClient.upload(bufferedInputStream, bufferedInputStream.available(),true);     


OffsetDateTime keyStart = OffsetDateTime.now();
OffsetDateTime keyExpiry = OffsetDateTime.now().plusDays(7);


UserDelegationKey userDelegationKey = blobServiceClient.getUserDelegationKey(keyStart, keyExpiry);

            BlobContainerSasPermission blobContainerSas = new BlobContainerSasPermission();
            blobContainerSas.setReadPermission(true);
            BlobServiceSasSignatureValues blobServiceSasSignatureValues = new BlobServiceSasSignatureValues(keyExpiry,
                    blobContainerSas);


String sas = blobClient.generateUserDelegationSas(blobServiceSasSignatureValues, userDelegationKey);


I found the answer from this link

Azure sdk for Java How to Setup User Delegation Key and Shared Authentication Signatures SAS

like image 150
Raj Avatar answered Oct 30 '25 20:10

Raj