Files
tiku-backend.net/Tiku.Api/Configuration/NetworkConfigurationExtensions.cs

85 lines
3.1 KiB
C#

using System.Net;
using Microsoft.AspNetCore.HttpOverrides;
using Tiku.Api.Options;
using Tiku.Application.Tenancy;
namespace Tiku.Api.Configuration;
internal static class NetworkConfigurationExtensions
{
internal static IServiceCollection AddNetworkConfiguration(
this IServiceCollection services,
IConfiguration configuration,
IHostEnvironment environment)
{
services.AddOptions<TenantResolutionOptions>()
.Bind(configuration.GetSection(TenantResolutionOptions.SectionName))
.Validate(
options => OptionsValidation.BeValidTenantResolutionOptions(options, configuration, environment.IsProduction()),
"Production requires formal platform hosts, non-wildcard AllowedHosts, and trusted proxy addresses.")
.ValidateOnStart();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedHost |
ForwardedHeaders.XForwardedProto;
options.ForwardLimit = 1;
options.KnownProxies.Clear();
options.KnownIPNetworks.Clear();
var resolution = configuration
.GetSection(TenantResolutionOptions.SectionName)
.Get<TenantResolutionOptions>() ?? new TenantResolutionOptions();
foreach (var address in resolution.TrustedProxyAddresses)
{
if (IPAddress.TryParse(address, out var proxy))
{
options.KnownProxies.Add(proxy);
}
}
});
services.AddOptions<DomainLifecycleOptions>()
.Bind(configuration.GetSection("TenantDomains"));
services.AddOptions<CorsOptions>()
.Bind(configuration.GetSection(CorsOptions.SectionName))
.ValidateDataAnnotations()
.Validate(
OptionsValidation.BeValidCorsOptions,
"CORS origins must be absolute HTTP/HTTPS origins, and credentials require explicit origins.")
.ValidateOnStart();
var corsOptions = configuration
.GetSection(CorsOptions.SectionName)
.Get<CorsOptions>() ?? new CorsOptions();
services.AddCors(options =>
{
options.AddPolicy(CorsOptions.PolicyName, policy =>
{
var origins = corsOptions.AllowedOrigins
.Where(origin => !string.IsNullOrWhiteSpace(origin))
.Select(origin => origin.Trim().TrimEnd('/'))
.Distinct(StringComparer.OrdinalIgnoreCase)
.ToArray();
if (origins.Length > 0)
{
policy.WithOrigins(origins);
}
policy
.WithHeaders(corsOptions.AllowedHeaders)
.WithMethods(corsOptions.AllowedMethods);
if (corsOptions.AllowCredentials)
{
policy.AllowCredentials();
}
});
});
return services;
}
}