Issue with SAS contain "+" sign

2024-08-06T07:31:47.95+00:00

Hi, I'm trying to create SAS token to access to the blob and using the code snippet below.

private static string GenerateBlobSasToken(BlobContainerClient containerClient, string blobFullPath)

{

// Get a reference to a blob

BlobClient blobClient = containerClient.GetBlobClient(blobFullPath);

// Ensure the blob exists

if (!blobClient.Exists())

{

throw new Exception($"Blob {blobFullPath} does not exist.");

}

BlobSasBuilder sasBuilder = new BlobSasBuilder

{

BlobContainerName = containerClient.Name,

BlobName = blobFullPath,

Resource = "b", // 'b' indicates that the shared access signature is for a blob

ExpiresOn = DateTimeOffset.UtcNow.AddDays(1).AddHours(1), // Set the expiry time for the SAS token,

StartsOn = DateTimeOffset.UtcNow.AddSeconds(-30), //Set the start time for the token (buffer by 30s)

ContentType = "application/x-mpegurl",

Protocol = SasProtocol.Https

};

// Set the permissions for the SAS token

sasBuilder.SetPermissions(BlobSasPermissions.Read);

// Use the storage account key to sign the SAS token

Uri sasUri = blobClient.GenerateSasUri(sasBuilder);

Console.WriteLine($"Generated SAS Url for : {blobFullPath} - {sasUri.ToString()} - {sasUri.AbsoluteUri}");

//return EncodeUrl(sasUri.ToString());

return sasUri.ToString();

}

the SAS token generated is as below:

https://mystorageaccount.blob.core.windows.net/video-assets/h264.m3u8?sv=2024-08-04&spr=https&st=2024-08-06T07:12:17Z&se=2024-08-07T08:12:47Z&sr=b&sp=r&rsct=application/x-mpegurl&sig=8Nqq8RO74WAzF+3Ab39Wk8T/oUAReEuWbVobIOtTxB0=

Payload (Query String) taken from the browser:

  1. sv: 2024-08-04
  2. spr: https
  3. st: 2024-08-06T07:12:17Z
  4. se: 2024-08-07T08:12:47Z
  5. sr: b
  6. sp: r
  7. rsct: application/x-mpegurl
  8. sig: 8Nqq8RO74WAzF 3Ab39Wk8T/oUAReEuWbVobIOtTxB0=

The question is why the SAS token generated is not compatible with the browser especially when it contain "+" sign. I tried with CURL then it works.

curl -I "https://mystorageaccount.blob.core.windows.net/video-assets/h264.m3u8?sv=2024-08-04&spr=https&st=2024-08-06T07%3A12%3A17Z&se=2024-08-07T08%3A12%3A47Z&sr=b&sp=r&rsct=application%2Fx-mpegurl&sig=8Nqq8RO74WAzF%2b3Ab39Wk8T/oUAReEuWbVobIOtTxB0%3D"

HTTP/1.1 200 OK

Content-Length: 16829

Content-Type: application/x-mpegurl

Content-MD5: xGl2kJ4bk+N+UoKkGLXAOA==

Last-Modified: Tue, 06 Aug 2024 07:12:47 GMT

Accept-Ranges: bytes

ETag: "<Etag>"

Vary: Origin

Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0

x-ms-request-id: <request id>

x-ms-version: 2024-08-04

x-ms-creation-time: Mon, 05 Aug 2024 10:45:10 GMT

x-ms-lease-status: unlocked

x-ms-lease-state: available

x-ms-blob-type: BlockBlob

x-ms-server-encrypted: true

Date: Tue, 06 Aug 2024 07:21:54 GMT

Azure Storage
Azure Storage
Globally unique resources that provide access to data management services and serve as the parent namespace for the services.
3,538 questions
0 comments No comments
{count} votes

Accepted answer
  1. Sumarigo-MSFT 47,471 Reputation points Microsoft Employee Moderator
    2024-08-06T12:22:27.1466667+00:00

    @Gobinath Vartharaju (DE-SWE/DIGITAL) Welcome to Microsoft Q&A Forum, Thank you for posting your query here!

    It looks like you're encountering an issue with the SAS token containing a "+" sign, which is causing compatibility issues with the browser. This is a common problem because the "+" character in URLs is often interpreted as a space by browsers.

    To resolve this issue, you can URL-encode the SAS token before using it in the browser. The "+" character should be replaced with "%2B". Here's how you can modify your code to URL-encode the SAS token:

    private static string GenerateBlobSasToken(BlobContainerClient containerClient, string blobFullPath)
    {
        // Get a reference to a blob
        BlobClient blobClient = containerClient.GetBlobClient(blobFullPath);
    
        // Ensure the blob exists
        if (!blobClient.Exists())
        {
            throw new Exception($"Blob {blobFullPath} does not exist.");
        }
    
        BlobSasBuilder sasBuilder = new BlobSasBuilder
        {
            BlobContainerName = containerClient.Name,
            BlobName = blobFullPath,
            Resource = "b", // 'b' indicates that the shared access signature is for a blob
            ExpiresOn = DateTimeOffset.UtcNow.AddDays(1).AddHours(1), // Set the expiry time for the SAS token,
            StartsOn = DateTimeOffset.UtcNow.AddSeconds(-30), //Set the start time for the token (buffer by 30s)
            ContentType = "application/x-mpegurl",
            Protocol = SasProtocol.Https
        };
    
        // Set the permissions for the SAS token
        sasBuilder.SetPermissions(BlobSasPermissions.Read);
    
        // Use the storage account key to sign the SAS token
        Uri sasUri = blobClient.GenerateSasUri(sasBuilder);
    
        // URL-encode the SAS token
        string encodedSasUri = Uri.EscapeUriString(sasUri.ToString());
    
        Console.WriteLine($"Generated SAS Url for : {blobFullPath} - {encodedSasUri} - {sasUri.AbsoluteUri}");
    
        return encodedSasUri;
    }
    

    This should ensure that the SAS token is compatible with the browser.

    It looks like the SAS token is working correctly with CURL, as indicated by the HTTP/1.1 200 OK response. The issue with the "+" sign in the SAS token causing compatibility problems in the browser can be resolved by URL-encoding the token.

    In your CURL command, the SAS token is URL-encoded, which is why it works. The "+" sign is replaced with %2B, and other special characters are also encoded. This ensures that the token is interpreted correctly by the browser.

    If you haven't already, you can modify your code to URL-encode the SAS token before using it in the browser. Here's the updated code snippet:

    Option 2:
    you can try URL encoding the signature before appending it to the SAS token. You can use the HttpUtility.UrlEncode method in the System.Web namespace to URL encode the signature.

    This code snippet uses the HttpUtility.UrlEncode method to URL encode the signature before appending it to the SAS token. This should ensure that the SAS token is compatible

    Please let us know if you have any further queries. I’m happy to assist you further.   


    Please do not forget to "Accept the answer” and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.

    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.