Skip to content

Commit

Permalink
Adding an app setting to allow CORS configuration (#9846)
Browse files Browse the repository at this point in the history
  • Loading branch information
soninaren authored Feb 1, 2024
1 parent a77bf00 commit 49732b0
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 13 deletions.
1 change: 1 addition & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
- Customers can opt-out of this behavior by setting `SendCanceledInvocationsToWorker` to `false` in host.json
- If a worker does not support CancellationTokens, cancelled invocations will not be sent to the worker
- Warn when `FUNCTIONS_WORKER_RUNTIME` is not set (#9799)
- Add an app setting to allow CORS configuration (#9846)
4 changes: 1 addition & 3 deletions src/WebJobs.Script.WebHost/Configuration/CorsOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Cors.Infrastructure;
using Microsoft.Extensions.Options;

Expand All @@ -23,7 +21,7 @@ public CorsOptionsSetup(IEnvironment env, IOptions<HostCorsOptions> hostCorsOpti

public void Configure(CorsOptions options)
{
if (_env.IsAnyLinuxConsumption())
if (_env.IsAnyLinuxConsumption() || _env.IsCorsConfigurationEnabled())
{
string[] allowedOrigins = _hostCorsOptions.Value.AllowedOrigins?.ToArray() ?? Array.Empty<string>();
var policyBuilder = new CorsPolicyBuilder(allowedOrigins);
Expand Down
9 changes: 8 additions & 1 deletion src/WebJobs.Script.WebHost/WebScriptHostBuilderExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Net.Http;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.Azure.WebJobs.Host.Config;
using Microsoft.Azure.WebJobs.Host.Executors;
Expand Down Expand Up @@ -125,11 +126,17 @@ public static IHostBuilder AddWebScriptHost(this IHostBuilder builder, IServiceP
services.TryAddSingleton<IJobHostMiddlewarePipeline, DefaultMiddlewarePipeline>();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, CustomHttpHeadersMiddleware>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, HstsConfigurationMiddleware>());
if (environment.IsAnyLinuxConsumption())

bool isAnyLinuxConsumption = environment.IsAnyLinuxConsumption();

if (isAnyLinuxConsumption || environment.IsCorsConfigurationEnabled())
{
services.AddSingleton<ICorsMiddlewareFactory, CorsMiddlewareFactory>();
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, JobHostCorsMiddleware>());
}

if (isAnyLinuxConsumption)
{
// EasyAuth must go after CORS, as CORS preflight requests can happen before authentication
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, JobHostEasyAuthMiddleware>());
}
Expand Down
5 changes: 5 additions & 0 deletions src/WebJobs.Script/Environment/EnvironmentExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ public static bool IsContainer(this IEnvironment environment)
&& runningInContainerValue;
}

public static bool IsCorsConfigurationEnabled(this IEnvironment environment)
{
return environment.GetEnvironmentVariable(EnableCorsConfiguration) == "1";
}

public static bool IsPersistentFileSystemAvailable(this IEnvironment environment)
{
return environment.IsWindowsAzureManagedHosting()
Expand Down
1 change: 1 addition & 0 deletions src/WebJobs.Script/Environment/EnvironmentSettingNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public static class EnvironmentSettingNames
public const string LinuxAzureAppServiceStorage = "WEBSITES_ENABLE_APP_SERVICE_STORAGE";
public const string CoreToolsEnvironment = "FUNCTIONS_CORETOOLS_ENVIRONMENT";
public const string RunningInContainer = "DOTNET_RUNNING_IN_CONTAINER";
public const string EnableCorsConfiguration = "FUNCTIONS_ENABLE_CORS_CONFIGURATION";

public const string ExtensionBundleSourceUri = "FUNCTIONS_EXTENSIONBUNDLE_SOURCE_URI";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ public async Task Invoke_HasCorsConfig_InvokesNext()
Assert.True(nextInvoked);
}

[Fact]
public async Task Invoke_OriginAllowed_AddsExpectedHeaders()
[Theory]
[InlineData(EnvironmentSettingNames.ContainerName, "foo")]
[InlineData(EnvironmentSettingNames.EnableCorsConfiguration, "1")]
public async Task Invoke_OriginAllowed_AddsExpectedHeaders(string appSettingName, string appSettingValue)
{
var envars = new Dictionary<string, string>()
{
{ EnvironmentSettingNames.ContainerName, "foo" },
{ appSettingName, appSettingValue }
};
var testEnv = new TestEnvironment(envars);
var testOrigin = "https://functions.azure.com";
Expand Down Expand Up @@ -107,12 +109,14 @@ public async Task Invoke_OriginAllowed_AddsExpectedHeaders()
Assert.Equal("true", allowCredsHeaderValues.FirstOrDefault());
}

[Fact]
public async Task Invoke_OriginNotAllowed_DoesNotAddHeaders()
[Theory]
[InlineData(EnvironmentSettingNames.ContainerName, "foo")]
[InlineData(EnvironmentSettingNames.EnableCorsConfiguration, "1")]
public async Task Invoke_OriginNotAllowed_DoesNotAddHeaders(string appSettingName, string appSettingValue)
{
var envars = new Dictionary<string, string>()
{
{ EnvironmentSettingNames.ContainerName, "foo" },
{ appSettingName, appSettingValue }
};
var testEnv = new TestEnvironment(envars);
var badOrigin = "http://badorigin.com";
Expand Down Expand Up @@ -161,12 +165,14 @@ public async Task Invoke_OriginNotAllowed_DoesNotAddHeaders()
Assert.False(response.Headers.TryGetValues("Access-Control-Allow-Methods", out allowMethods));
}

[Fact]
public async Task Invoke_Adds_AccessControlAllowMethods()
[Theory]
[InlineData(EnvironmentSettingNames.ContainerName, "foo")]
[InlineData(EnvironmentSettingNames.EnableCorsConfiguration, "1")]
public async Task Invoke_Adds_AccessControlAllowMethods(string appSettingName, string appSettingValue)
{
var envars = new Dictionary<string, string>()
{
{ EnvironmentSettingNames.ContainerName, "foo" },
{ appSettingName, appSettingValue }
};
var testEnv = new TestEnvironment(envars);
var testOrigin = "https://functions.azure.com";
Expand Down

0 comments on commit 49732b0

Please sign in to comment.