# Implement Azure Blob Storage Using Presigned URL in .NET Core and JavaScript

URL: https://answers.mindstick.com/blog/284/implement-azure-blob-storage-using-presigned-url-in-dot-net-core-and-javascript

Cloud file storage is now a standard requirement for modern web applications. Whether you are building a social media platform, blogging system, e-commerce site, or enterprise dashboard, users expect fast and secure file uploads.
One of the best ways to securely upload files to Azure Blob Storage is by using
Presigned URLs, commonly known in Azure as SAS (Shared Access Signature) URLs.
Instead of uploading files through your server, the backend generates a temporary secure upload URL, and the frontend uploads directly to Azure Blob Storage.
This approach improves:
PerformanceSecurityScalabilityServer resource usage
According to 
Microsoft Learn Azure SAS Documentation, SAS provides delegated and time-limited access to Azure Storage resources.
What is a Presigned URL (SAS URL)?
A SAS URL is a temporary URL that grants limited access to a blob or container.
The URL contains:
Expiration timeAllowed operationsResource pathSecurity signature
Example:
https://myaccount.blob.core.windows.net/uploads/image.png?
sv=2024-01-01and
sr=band
sig=xxxxx
The frontend can use this URL to upload files directly without exposing Azure credentials.
Why Use SAS URLs?
Traditional Upload Flow
Browser → Your Server → Azure Blob Storage
Problems:
Large server bandwidth usageSlow uploadsHigh server memory consumptionDifficult scaling
SAS Upload Flow
Browser → Azure Blob Storage
          ↑
     SAS URL from API
Benefits:
Faster uploadsReduced server loadBetter scalabilitySecure temporary accessIdeal for large files
Azure Blob Storage Architecture
Frontend (JavaScript)
        ↓
ASP.NET Core API
        ↓
Generate SAS URL
        ↓
Frontend uploads directly
        ↓
Azure Blob Storage
Step 1: Create Azure Storage Account
Go to:
Microsoft Azure Portal
Create:
Storage AccountBlob ContainerEnable Blob Storage
Example container:
uploads
Step 2: Install NuGet Package
Install Azure Blob SDK.
dotnet add package Azure.Storage.Blobs
Step 3: Add Configuration
appsettings.json
{
  "AzureBlob": {
    "ConnectionString": "YOUR_CONNECTION_STRING",
    "ContainerName": "uploads",
    "AccountName": "youraccount",
    "AccountKey": "yourkey"
  }
}
Step 4: Create SAS Service
BlobStorageService.cs
using Azure.Storage;
using Azure.Storage.Blobs;
using Azure.Storage.Sas;
public class BlobStorageService
{
    private readonly IConfiguration _configuration;
    public BlobStorageService(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    public string GenerateUploadSasUrl(string fileName)
    {
        var accountName = _configuration["AzureBlob:AccountName"];
        var accountKey = _configuration["AzureBlob:AccountKey"];
        var containerName = _configuration["AzureBlob:ContainerName"];
        var credential = new StorageSharedKeyCredential(
            accountName,
            accountKey
        );
        var blobUri = new Uri(
            $"https://{accountName}.blob.core.windows.net/{containerName}/{fileName}"
        );
        BlobSasBuilder sasBuilder = new BlobSasBuilder
        {
            BlobContainerName = containerName,
            BlobName = fileName,
            Resource = "b",
            StartsOn = DateTimeOffset.UtcNow,
            ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(15)
        };
        sasBuilder.SetPermissions(BlobSasPermissions.Create |
                                  BlobSasPermissions.Write);
        var sasToken = sasBuilder.ToSasQueryParameters(credential).ToString();
        return $"{blobUri}?{sasToken}";
    }
}
Step 5: Create API Endpoint
UploadController.cs
using Microsoft.AspNetCore.Mvc;
[ApiController]
[Route("api/upload")]
public class UploadController : ControllerBase
{
    private readonly BlobStorageService _blobStorageService;
    public UploadController(BlobStorageService blobStorageService)
    {
        _blobStorageService = blobStorageService;
    }
    [HttpGet("sas-url")]
    public IActionResult GetSasUrl(string fileName)
    {
        var sasUrl = _blobStorageService.GenerateUploadSasUrl(fileName);
        return Ok(new
        {
            uploadUrl = sasUrl
        });
    }
}
Step 6: Register Service
Program.cs
builder.Services.AddScopedandlt;BlobStorageServiceandgt;();
Step 7: Frontend JavaScript Upload
HTML
andlt;input type="file" id="fileInput" /andgt;
andlt;button onclick="uploadFile()"andgt;Uploadandlt;/buttonandgt;
JavaScript
async function uploadFile() {
    const fileInput = document.getElementById("fileInput");
    const file = fileInput.files[0];
    if (!file) {
        alert("Select file");
        return;
    }
    // Step 1: Get SAS URL
    const response = await fetch(
        `/api/upload/sas-url?fileName=${encodeURIComponent(file.name)}`
    );
    const data = await response.json();
    // Step 2: Upload directly to Azure
    const uploadResponse = await fetch(data.uploadUrl, {
        method: "PUT",
        headers: {
            "x-ms-blob-type": "BlockBlob",
            "Content-Type": file.type
        },
        body: file
    });
    if (uploadResponse.ok) {
        alert("File uploaded successfully");
    } else {
        alert("Upload failed");
    }
}
How It Works
Backend
Generates secure temporary URLDefines permissionsSets expiration time
Frontend
Requests upload URLUploads file directly to Azure Blob StorageNo file passes through your API server.
Important SAS Permissions
Permission
Meaning
Read
Download file
Write
Modify blob
Create
Upload new blob
Delete
Remove blob
List
List container files
Use minimum required permissions.
Microsoft recommends limiting permissions and expiration scope for security.
Production Security Best Practices
1. Use Short Expiration
Good:
ExpiresOn = DateTimeOffset.UtcNow.AddMinutes(10)
Bad:
ExpiresOn = DateTimeOffset.UtcNow.AddYears(1)
2. Generate URLs Server-Side Only
Never expose:
Storage account keyConnection string
3. Validate File Types
Example:
string[] allowedExtensions = { ".jpg", ".png", ".pdf" };
4. Use Random File Names
Avoid collisions.
var fileName = $"{Guid.NewGuid()}{extension}";
5. Restrict Permissions
Only grant required access.
Example:
BlobSasPermissions.Create | BlobSasPermissions.Write
NOT:
BlobSasPermissions.All
Large File Upload Optimization
For large files:
Use chunk uploadsUse parallel uploadsUse resumable uploads
Azure Blob Storage supports block-based uploads efficiently.
Common Errors
1. Signature Did Not Match
Usually caused by:
Wrong account keyInvalid blob pathExpired SAS token
This is a common developer issue discussed in Azure community forums.
2. CORS Error
Configure Azure Storage CORS.
Azure Portal:
Storage Account
→ Resource Sharing (CORS)
Add:
Allowed Origins: *
Allowed Methods: PUT, GET
Allowed Headers: *
3. Authentication Failed
Check:
SAS expirationBlob permissionsContainer name
Advanced Production Architecture
Client
   ↓
API Gateway
   ↓
Auth Validation
   ↓
Generate SAS URL
   ↓
Azure Blob Storage
Optional additions:
CDNVirus scanningQueue processingThumbnail generation
User Delegation SAS (Recommended)
Microsoft recommends using User Delegation SAS instead of account-key SAS because it uses Microsoft Entra credentials for better security.
Benefits:
Better securityNo direct account key exposureRBAC integration
Real-World Use Cases
Social Media Platforms
Image uploadsVideo uploads
Blogging Systems
Thumbnail uploadsPDF attachments
E-Commerce
Product image uploads
Enterprise Apps
Document managementReport uploads
Performance Benefits
Traditional Upload
SAS Upload
High server load
Minimal server load
Slow
Faster
Expensive scaling
Better scalability
Large memory usage
Direct cloud upload
Conclusion
Using Azure Blob Storage with SAS URLs is one of the best approaches for modern scalable applications.
It provides:
Secure uploadsFaster performanceReduced backend loadBetter scalabilityCloud-native architecture
The combination of:
ASP.NET Core backendJavaScript frontendAzure Blob Storagecreates a highly scalable and production-ready upload system suitable for enterprise applications.
For official Azure documentation and SDK examples, see:
Azure SAS Overview Documentation
Azure Blob SAS JavaScript Guide
Azure Blob Storage JavaScript SDK
