Skip to content

Instantly share code, notes, and snippets.

@snobu
Created September 7, 2023 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save snobu/e9e532f5032cf1948a391fefb8e75f07 to your computer and use it in GitHub Desktop.
Save snobu/e9e532f5032cf1948a391fefb8e75f07 to your computer and use it in GitHub Desktop.
Dynamic CORS policy update for ASP.NET (.NET Framework)
using System;
using System.Configuration;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Cors;
using System.Web.Http;
using System.Web.Http.Cors;
using System.IO;
using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Blob;
using Microsoft.Azure.Storage.Auth;
using System.Diagnostics;
namespace WebAppManyCors
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Enable CORS using a custom policy provider
var corsPolicyProvider = new CustomCorsPolicyProvider();
config.EnableCors(corsPolicyProvider);
// Configure a custom route for updating CORS settings
config.Routes.MapHttpRoute(
name: "UpdateCorsRoute",
routeTemplate: "api/updatecors",
defaults: new { controller = "Cors", action = "UpdateCors" }
);
}
public class CorsController : ApiController
{
[HttpPost]
[Route("api/updatecors")]
public IHttpActionResult UpdateCors()
{
try
{
var blobContainerName = ConfigurationManager.AppSettings["BlobContainerName"];
var blobName = ConfigurationManager.AppSettings["BlobName"];
// Fetch the updated CORS domain list from Blob Storage using Managed Identity
var updatedCorsDomains = GetCorsDomainsFromBlob(blobContainerName, blobName).Result;
// Update the CORS policy provider with the new domains
var corsPolicyProvider = new CustomCorsPolicyProvider();
corsPolicyProvider.UpdateCorsPolicy(updatedCorsDomains);
return Ok("CORS settings updated successfully.");
}
catch (Exception ex)
{
// Handle exceptions here (e.g., log the error)
return InternalServerError(ex);
}
}
private async Task<string> GetCorsDomainsFromBlob(string containerName, string blobName)
{
try
{
var storageAccountName = ConfigurationManager.AppSettings["StorageAccountName"];
var storageAccountKey = ConfigurationManager.AppSettings["StorageAccountKey"];
StorageCredentials storageCredentials = new StorageCredentials(storageAccountName, storageAccountKey);
CloudStorageAccount storageAccount = new CloudStorageAccount(storageCredentials, true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference(containerName);
CloudBlockBlob blob = container.GetBlockBlobReference(blobName);
// Check if the blob exists
if (blob.Exists())
{
// Download the blob content
using (MemoryStream ms = new MemoryStream())
{
// ConfigureAwait to avoid ASP.NET thread scheduler deadlock
await blob.DownloadToStreamAsync(ms).ConfigureAwait(false);
ms.Position = 0;
// Read the content into a string
using (StreamReader reader = new StreamReader(ms))
{
string blobContent = await reader.ReadToEndAsync();
return blobContent;
}
}
}
else
{
throw new InvalidOperationException("Blob does not exist.");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error downloading blob: {ex.Message}");
throw;
}
}
}
public class CustomCorsPolicyProvider : Attribute, ICorsPolicyProvider
{
private CorsPolicy corsPolicy;
public CustomCorsPolicyProvider()
{
corsPolicy = new CorsPolicy
{
AllowAnyMethod = true,
AllowAnyHeader = true,
};
}
public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return Task.FromResult(corsPolicy);
}
public void UpdateCorsPolicy(string corsDomains)
{
// Update the CORS policy with the new domains
corsPolicy.Origins.Clear();
// Split the corsDomains string into a list of origins
var domains = corsDomains.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var domain in domains)
{
corsPolicy.Origins.Add(domain);
Trace.TraceInformation($"CORS domain added: {domain}");
}
foreach (string o in corsPolicy.Origins)
{
Trace.TraceInformation($"corsPolicy now contains: {o}");
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment