Skip to content

Commit

Permalink
supporting EasyAuth for Linux Consumption in the functions host (Azur…
Browse files Browse the repository at this point in the history
…e#6006)

* cherry pick v2 changes

* fixed csproj
  • Loading branch information
madelinegordon authored Jun 26, 2020
1 parent 242a4c5 commit 1103b5f
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 5 deletions.
14 changes: 14 additions & 0 deletions src/WebJobs.Script.WebHost/Configuration/HostEasyAuthOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.Extensions.Configuration;

namespace Microsoft.Azure.WebJobs.Script.WebHost.Configuration
{
public class HostEasyAuthOptions
{
public bool SiteAuthEnabled { get; set; }

public string SiteAuthClientId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) .NET Foundation. All rights reserved.
// 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.Azure.WebJobs.Script.Configuration;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;

namespace Microsoft.Azure.WebJobs.Script.WebHost.Configuration
{
public class HostEasyAuthOptionsSetup : IConfigureOptions<HostEasyAuthOptions>
{
private readonly IEnvironment _env;

public HostEasyAuthOptionsSetup(IEnvironment env)
{
_env = env;
}

public void Configure(HostEasyAuthOptions options)
{
options.SiteAuthEnabled = IsSiteAuthEnabled();
options.SiteAuthClientId = _env.GetEnvironmentVariable(EnvironmentSettingNames.EasyAuthClientId);
}

private bool IsSiteAuthEnabled()
{
string enabledString = _env.GetEnvironmentVariable(EnvironmentSettingNames.EasyAuthEnabled);
if (bool.TryParse(enabledString, out bool result))
{
return result;
}
if (int.TryParse(enabledString, out int enabledInt))
{
return Convert.ToBoolean(enabledInt);
}
return false;
}
}
}
2 changes: 1 addition & 1 deletion src/WebJobs.Script.WebHost/Management/InstanceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ private async Task Assign(HostAssignmentContext assignmentContext)
private async Task ApplyContext(HostAssignmentContext assignmentContext)
{
_logger.LogInformation($"Applying {assignmentContext.Environment.Count} app setting(s)");
assignmentContext.ApplyAppSettings(_environment);
assignmentContext.ApplyAppSettings(_environment, _logger);

// We need to get the non-PlaceholderMode script Path so we can unzip to the correct location.
// This asks the factory to skip the PlaceholderMode check when configuring options.
Expand Down
50 changes: 50 additions & 0 deletions src/WebJobs.Script.WebHost/Middleware/JobHostEasyAuthMiddleware.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.AppService.Middleware.AspNetCoreMiddleware;
using Microsoft.Azure.WebJobs.Script.Middleware;
using Microsoft.Azure.WebJobs.Script.WebHost.Configuration;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace Microsoft.Azure.WebJobs.Script.WebHost.Middleware
{
public class JobHostEasyAuthMiddleware : IJobHostHttpMiddleware
{
private readonly IConfiguration _configuration;
private RequestDelegate _invoke;

public JobHostEasyAuthMiddleware(IOptions<HostEasyAuthOptions> hostEasyAuthOptions, IConfiguration configuration)
{
_configuration = configuration ?? throw new ArgumentNullException(nameof(configuration));

RequestDelegate contextNext = async context =>
{
if (context.Items.Remove(ScriptConstants.EasyAuthMiddlewareRequestDelegate, out object requestDelegate) && requestDelegate is RequestDelegate next)
{
await next(context);
}
};
if (hostEasyAuthOptions.Value.SiteAuthEnabled)
{
var easyAuthMiddleware = new EasyAuthMiddleware(contextNext, _configuration, AppService.Middleware.Functions.FunctionsHostingEnvironment.LinuxConsumption);
_invoke = easyAuthMiddleware.InvokeAsync;
}
else
{
_invoke = contextNext;
}
}

public async Task Invoke(HttpContext context, RequestDelegate next)
{
context.Items.Add(ScriptConstants.EasyAuthMiddlewareRequestDelegate, next);
await _invoke(context);
}
}
}
2 changes: 0 additions & 2 deletions src/WebJobs.Script.WebHost/Models/EasyAuthSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,5 @@ public class EasyAuthSettings
public bool SiteAuthEnabled { get; set; }

public string SiteAuthClientId { get; set; }

public bool? SiteAuthAutoProvisioned { get; set; }
}
}
19 changes: 17 additions & 2 deletions src/WebJobs.Script.WebHost/Models/HostAssignmentContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

Expand Down Expand Up @@ -112,13 +113,12 @@ public bool Equals(HostAssignmentContext other)
return SiteId == other.SiteId && LastModifiedTime.CompareTo(other.LastModifiedTime) == 0;
}

public void ApplyAppSettings(IEnvironment environment)
public void ApplyAppSettings(IEnvironment environment, ILogger logger)
{
foreach (var pair in Environment)
{
environment.SetEnvironmentVariable(pair.Key, pair.Value);
}

if (CorsSettings != null)
{
environment.SetEnvironmentVariable(EnvironmentSettingNames.CorsSupportCredentials, CorsSettings.SupportCredentials.ToString());
Expand All @@ -129,6 +129,21 @@ public void ApplyAppSettings(IEnvironment environment)
environment.SetEnvironmentVariable(EnvironmentSettingNames.CorsAllowedOrigins, allowedOrigins);
}
}

if (EasyAuthSettings != null)
{
// App settings take precedence over site config for easy auth enabled.
if (string.IsNullOrEmpty(environment.GetEnvironmentVariable(EnvironmentSettingNames.EasyAuthEnabled)))
{
logger.LogDebug($"ApplyAppSettings is adding {EnvironmentSettingNames.EasyAuthEnabled} = {EasyAuthSettings.SiteAuthEnabled.ToString()}");
environment.SetEnvironmentVariable(EnvironmentSettingNames.EasyAuthEnabled, EasyAuthSettings.SiteAuthEnabled.ToString());
}
else
{
logger.LogDebug($"ApplyAppSettings operating on existing {EnvironmentSettingNames.EasyAuthEnabled} = {environment.GetEnvironmentVariable(EnvironmentSettingNames.EasyAuthEnabled)}");
}
environment.SetEnvironmentVariable(EnvironmentSettingNames.EasyAuthClientId, EasyAuthSettings.SiteAuthClientId);
}
}
}
}
2 changes: 2 additions & 0 deletions src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@
<PackageReference Include="DotNetTI.BreakingChangeAnalysis" Version="1.1.0-preview" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.AppService.Middleware.Functions" Version="1.0.0-preview6" />
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client" Version="2.0.11020001-fabe022e" />
<PackageReference Include="DotNetTI.BreakingChangeAnalysis" Version="1.0.5-preview" />
<PackageReference Include="Microsoft.Azure.Services.AppAuthentication" Version="1.0.3" />
<PackageReference Include="Microsoft.Azure.Storage.File" Version="11.1.0" />
<PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="4.0.1" />
Expand Down
5 changes: 5 additions & 0 deletions src/WebJobs.Script.WebHost/WebScriptHostBuilderExtension.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static IHostBuilder AddWebScriptHost(this IHostBuilder builder, IServiceP
services.ConfigureOptions<HostCorsOptionsSetup>();
services.ConfigureOptions<CorsOptionsSetup>();
services.ConfigureOptions<AppServiceOptionsSetup>();
services.ConfigureOptions<HostEasyAuthOptionsSetup>();
})
.AddScriptHost(webHostOptions, configLoggerFactory, metricsLogger, webJobsBuilder =>
{
Expand Down Expand Up @@ -92,6 +93,10 @@ public static IHostBuilder AddWebScriptHost(this IHostBuilder builder, IServiceP
services.TryAddSingleton<IScriptWebHookProvider>(p => p.GetService<DefaultScriptWebHookProvider>());
services.TryAddSingleton<IWebHookProvider>(p => p.GetService<DefaultScriptWebHookProvider>());
services.TryAddSingleton<IJobHostMiddlewarePipeline, DefaultMiddlewarePipeline>();
if (environment.IsLinuxConsumption())
{
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, JobHostEasyAuthMiddleware>());
}
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, CustomHttpHeadersMiddleware>());
services.TryAddEnumerable(ServiceDescriptor.Singleton<IJobHostHttpMiddleware, HstsConfigurationMiddleware>());
if (environment.IsLinuxConsumption())
Expand Down
1 change: 1 addition & 0 deletions src/WebJobs.Script/Config/ConfigurationSectionNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ public static class ConfigurationSectionNames
public const string Http = Extensions + ":http";
public const string Hsts = Http + ":hsts";
public const string CustomHttpHeaders = Http + ":customHeaders";
public const string EasyAuth = "easyauth";
}
}
6 changes: 6 additions & 0 deletions src/WebJobs.Script/Environment/EnvironmentSettingNames.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Azure.AppService.Proxy.Runtime.Configuration.Policies;

namespace Microsoft.Azure.WebJobs.Script
{
public static class EnvironmentSettingNames
Expand Down Expand Up @@ -92,5 +94,9 @@ public static class EnvironmentSettingNames
// CORS settings
public const string CorsAllowedOrigins = "CORS_ALLOWED_ORIGINS";
public const string CorsSupportCredentials = "CORS_SUPPORT_CREDENTIALS";

// EasyAuth settings
public const string EasyAuthClientId = "WEBSITE_AUTH_CLIENT_ID";
public const string EasyAuthSigningKey = "WEBSITE_AUTH_SIGNING_KEY";
}
}
1 change: 1 addition & 0 deletions src/WebJobs.Script/ScriptConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public static class ScriptConstants
public const string JobHostMiddlewarePipelineRequestDelegate = "MS_JobHostMiddlewarePipelineRequestDelegate";
public const string HstsMiddlewareRequestDelegate = "MS_HstsMiddlewareRequestDelegate";
public const string CorsMiddlewareRequestDelegate = "MS_CorsMiddlewareRequestDelegate";
public const string EasyAuthMiddlewareRequestDelegate = "MS_EasyAuthMiddlewareRequestDelegate";

public const string LegacyPlaceholderTemplateSiteName = "FunctionsPlaceholderTemplateSite";

Expand Down

0 comments on commit 1103b5f

Please sign in to comment.