Introduction:
When teams build secure document-sharing solutions on Azure, they often need to balance strong internal authentication with simple external access. Internal users should sign in with Microsoft Entra ID, but external recipients may only need a time-limited link to download a file without signing in.
That requirement leads directly to Shared Access Signatures (SAS). However, not every SAS type supports every sharing pattern. In this sample, the goal is to upload a file, define a reusable container-level access policy, and generate a URL that can be centrally controlled through that policy. That is why this app uses Service SAS rather than a User Delegation SAS.
This article walks through the complete scenario, the Blazor implementation approach, the Azure Storage configuration, and the architectural reasoning behind the SAS choice. It also compares User Delegation SAS, Service SAS, and Account SAS so you can choose the right option for your own solution.
Scenario
A common business requirement is to allow internal users to sign in with Microsoft Entra ID, upload a document to Azure Blob Storage, configure a stored access policy on the container, and generate a URL that can be shared with external recipients for time-limited read access.
That is the exact scenario implemented in `MCG.Blazor.StorageSasDemo`.
The app uses:
– Blazor Web App on .NET 10
– Bootstrap for the UI
– Microsoft Entra ID for user sign-in
– Azure Blob Storage for uploads
– A shared-key storage connection string to create stored access policies and Service SAS URLs
Why does this scenario use Service SAS?
This scenario depends on a stored access policy at the container level. A stored access policy is useful because it lets you:
– centralize the start time and expiry on the container
– issue SAS URLs that reference a policy identifier instead of embedding all limits directly in the token
– revoke or rotate access by changing or deleting the policy
That design works with Service SAS but not with User Delegation SAS.
Why does User Delegation SAS not work here?
A User Delegation SAS is signed with a user delegation key obtained through Microsoft Entra credentials. It is excellent for avoiding shared keys and authorizing access based on Azure AD identities.
However, the User Delegation SAS has an important limitation for this scenario: it does not support stored access policies.
That means you cannot:
– Create a container stored access policy
– generate a blob SAS that references the stored access policy identifier
– centrally revoke previously issued links by changing the stored access policy
Because this sample is specifically about creating a reusable, container-level policy and issuing shareable URLs from that policy, **Service SAS is the correct fit**.
Service SAS vs User Delegation SAS vs Account SAS
User Delegation SAS
Use User Delegation SAS when:
– your app authenticates to Azure Storage with Microsoft Entra ID
– You want to avoid shared keys
– You do not need stored access policies
– You want the SAS to be tied to a user delegation key lifecycle
Key characteristics:
– signed with a user delegation key
– preferred for blob and Data Lake workloads when possible
– does not support stored access policies
– strongest choice when you want Azure AD-based signing instead of account keys
Service SAS
Use Service SAS when:
– You need a SAS for a specific blob, file, queue, or table resource
– You need to reference a stored access policy
– You are using a storage account shared key to sign the SAS
Key characteristics:
– signed with the storage account shared key
– can target a blob, container, file share item, queue, or table resource depending on the service
– supports stored access policies
– ideal for this sample because the SAS is generated from a named container policy
Account SAS
Use Account SAS when:
– You need permission at the storage account level
– You need access that spans service boundaries or service-level operations
– You need capabilities beyond a single blob or container
Key characteristics:
– signed with the storage account shared key
– can grant access across Blob, Queue, Table, and File services
– can authorize service-level and account-level operations
– broader and more powerful than Service SAS, so it should be used carefully
Application Functionality
The sample is intentionally simple:
1. The user signs in with Microsoft Entra ID.
2. The Blazor page accepts a file upload.
3. The server uploads the blob to a selected container.
4. The user saves a read-only stored access policy on that container.
5. The app generates a Service SAS URL for the blob by using the policy identifier.
1. Configure Microsoft Entra ID
Update `appsettings.json` placeholders or environment settings for:
– AzureAd:TenantId
– AzureAd:ClientId
– AzureAd:ClientSecret
– AzureAd:CallbackPath
– AzureAd:SignedOutCallbackPath
For local development, use the same redirect URI pattern as the main app, for example:
– https://localhost:{port}/signin-oidc
2. Store the Azure Storage connection string securely
Do not commit the connection string to source control.
Use User Secrets from the `MCG.Blazor.StorageSasDemo` directory:
powershell:
dotnet user-secrets set “StorageDemo:ConnectionString” “<your-shared-key-connection-string>”
Permission:
Least privileged role required: Storage Blob Data Contributor (Container Level)
3. Run the App
4. Use the demo
1. Sign in with Microsoft Entra ID.
2. Enter or confirm the container name.
3. Select a file and upload it.
4. Create or update a stored access policy such as `download-policy`.
5. Generate the Service SAS URL.
6. Share the generated URL with the recipient.
Notes:
- Anyone who possesses the generated SAS URL can use it until it expires or the stored access policy is changed or removed.
- Because Service SAS uses a shared key, protect the storage account key carefully and rotate it in accordance with your security policy.
Github Repo : https://github.com/gowthamece/EntraID-Apps/tree/master/MCG.Blazor.StorageSasDemo

Leave a Reply