Created
September 7, 2023 11:55
-
-
Save snobu/e9e532f5032cf1948a391fefb8e75f07 to your computer and use it in GitHub Desktop.
Dynamic CORS policy update for ASP.NET (.NET Framework)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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