Private Blob URL access

Wajih ARFAOUI 0 Reputation points
2025-03-12T15:40:06.4266667+00:00

Hello,

I would like to know which is the best approach to be able to share urls of files stored in my blob storage that can be just accessible by an authorised group of people.

I am using copilot for creating a custom chatbot, this chatbot when answering questions will provide the urls of files he used for creating the answer and by clicking on the urls in the browser i want just authorised people to be able to see the content of that file otherwise it shows an error !

I appreciate your help

Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
3,192 questions
{count} votes

2 answers

Sort by: Most helpful
  1. Vinod Kumar Reddy Chilupuri 4,185 Reputation points Microsoft External Staff Moderator
    2025-03-13T12:59:55.7733333+00:00

    Hi Wajih ARFAOUI,

    To restrict access to a link and enforce authentication before showing the content, you can use Shared Access Signatures (SAS) tokens with specific permissions. By delegating SAS access at either the container level or the blob level, you can control who can access the content based on the permissions assigned to the SAS token.

    • Azure AD Authentication: Configure your blob storage to use Azure AD for authentication. This way, users will need to log in with their Azure AD credentials to access the files. You can assign roles to specific users or groups to control access. This adds a layer of security, as users must log in with their Azure AD accounts, which can be managed and controlled centrally.
    • User Delegation SAS: Use a User Delegation SAS (Shared Access Signature) that is secured with Azure AD credentials instead of the storage account key. This ensures that only authenticated users can access the files. Only authenticated users can generate and use the SAS token, ensuring that even if someone has the link, they cannot access the content without proper authentication.  
    • Private Blob Containers with Backend Service: Keep your blob containers private and create a backend service (e.g., an Azure Function) that retrieves the files. The backend service can check the user's authentication and authorization before providing access to the files. This adds an additional layer of control, as the backend service can enforce business logic, such as checking user roles or permissions before granting access to the files.

    Here are some steps to configure Azure AD authentication for your blob storage

    • Assign Azure Roles: Assign Azure roles to users or groups that need access to the blob storage. You can do this in the Azure portal by navigating to your storage account, selecting "Access control (IAM)," and adding role assignments.  
    • Generate User Delegation SAS: Create a User Delegation SAS for the blob storage. This SAS token will be secured with Azure AD credentials and will require users to authenticate before accessing the files.  
    • Integrate with Your Chatbot: Ensure your chatbot generates URLs with the User Delegation SAS token. When users click on the URLs, they will be prompted to log in with their Azure AD credentials if they are not already authenticated.

    By implementing Azure AD authentication, using User Delegation SAS tokens, and keeping your blob containers private with a backend service, you effectively restrict access to your Azure Blob Storage files. This ensures that only authenticated users with the appropriate permissions can access the content.

    Hope the above suggestion helps. Please let us know if you have any further queries.
    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. 

    User's image


  2. Venkatesan S 2,820 Reputation points Microsoft External Staff Moderator
    2025-03-17T12:45:41.36+00:00

    Hi @Wajih ARFAOUI,

    You can achieve this is to use an API Gateway (Proxy) with Azure AD authentication instead of exposing SAS URLs directly.

    You can set up a secure API that enforces authentication before allowing users to download files from Azure Blob Storage.

    1. Register an Azure AD App for authentication.
         Create a single tenant app with redirect uri `https://jwt.ms` and now, fetch the clientId, tenantId, Client-secret from the Registered app.
         ``` 2. **Set Up Blob Storage with Proper Permissions**.
              Now, Go to **Storage Account** → **Access Control (IAM)** → Click **Add role assignment** and assign a `Storage Blob Data Reader` or `Storage Blob Data Contributor` role to your groups which people to access.
      
      
    2. Create a Secure API (ASP.NET Core) to serve files. Create an ASP.NET core project and adding necessary packages. Configure appsettings.json Replace values with your Azure AD and Storage Account details:
           {
             "AzureAd": {
             "Instance": "https://login.microsoftonline.com/",
             "TenantId": "YOUR_TENANT_ID",
              "ClientId": "YOUR_CLIENT_ID",
             "ClientSecret": "YOUR_CLIENT_SECRET"
             },
           "BlobStorage": {
             "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=YOUR_STORAGE_ACCOUNT;AccountKey=YOUR_ACCOUNT_KEY;EndpointSuffix=core.windows.net",
             "ContainerName": "secure-files"
             },
             "AllowedUsers": [
             "user1@example.com",
             "user2@example.com"
             ]
           }
      
      Modify Program.cs to enable Azure AD authentication:
       using Microsoft.AspNetCore.Authentication.JwtBearer;
       using Microsoft.Identity.Web;
       using Azure.Storage.Blobs;
       
       var builder = WebApplication.CreateBuilder(args);
       var configuration = builder.Configuration;
       
       builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddMicrosoftIdentityWebApi(builder.Configuration.GetSection("AzureAd"));
       
       builder.Services.AddAuthorization();
       
       builder.Services.AddSingleton(new BlobServiceClient(builder.Configuration["BlobStorage:ConnectionString"])
       );
       
       builder.Services.AddControllers();
       var app = builder.Build();
       
       app.UseAuthentication();
       app.UseAuthorization();
       app.MapControllers();
       app.Run();
    

    Create FileController.cs:

       using System.Security.Claims;
       using Azure.Storage.Blobs;
       using Microsoft.AspNetCore.Authorization;
       using Microsoft.AspNetCore.Mvc;
       
       [Authorize] // Requires authentication
       [ApiController]
       [Route("api/files")]
       public class FileController : ControllerBase
       {
        private readonly BlobServiceClient _blobServiceClient;
        private readonly List<string> _allowedUsers;
       
        public FileController(BlobServiceClient blobServiceClient, IConfiguration configuration)
        {
            _blobServiceClient = blobServiceClient;
            _allowedUsers = configuration.GetSection("AllowedUsers").Get<List<string>>() ?? new List<string>();
        }
       
        [HttpGet("download")]
        public async Task<IActionResult> DownloadFile(string fileName)
        {
            var userEmail = User.FindFirst(ClaimTypes.Email)?.Value;
            
            // Check if user is authorized
            if (userEmail == null || !_allowedUsers.Contains(userEmail))
            {
                return Forbid(); // 403 Forbidden
            }
       
            // Get Blob Storage container
            var containerClient = _blobServiceClient.GetBlobContainerClient("secure-files");
            var blobClient = containerClient.GetBlobClient(fileName);
       
            // Check if file exists
            if (!await blobClient.ExistsAsync())
            {
                return NotFound("File not found.");
            }
       
            // Stream the file
            var stream = await blobClient.OpenReadAsync();
            return File(stream, "application/octet-stream", fileName);
        }
       }
    

    Your API will start at https://localhost:5001 and for testing purpose

    az login
    az account get-access-token --resource api://YOUR_CLIENT_ID`
    
    1. Test API with tools:
    • GET https://localhost:5001/api/files/download?fileName=myfile.pdf
    • Headers → Add:

    Authorization: Bearer <ACCESS_TOKEN>

    If the blobs are downloaded from the above app, the users were authorized; otherwise, you will receive a 403 Forbidden error.

    Hope this answer helps! 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

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.