using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; using System.Collections.Generic; using System.Linq; namespace NetworkResurrector.Api.Swagger { public static class SwaggerExtensions { public static IServiceCollection AddSwagger(this IServiceCollection services) { services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "NetworkResurrector API", Version = "v1" }); c.AddSecurityDefinition("Basic", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = @"JWT Authorization header using the Basic scheme. Enter 'Basic' [space] and then your token in the text input below. Example: 'Basic 12345abcdef'", Name = "Authorization", Scheme = "Basic", Type = SecuritySchemeType.ApiKey }); c.AddSecurityRequirement(new OpenApiSecurityRequirement() { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Basic" }, Scheme = "Basic", Name = "Authorization", In = ParameterLocation.Header }, new List() } }); c.OperationFilter(); c.SchemaFilter(); c.CustomSchemaIds(type => type.ToString()); }); return services; } public static IApplicationBuilder ConfigureSwagger(this IApplicationBuilder applicationBuilder) { applicationBuilder.UseSwagger(c => { c.PreSerializeFilters.Add((swagger, httpRequest) => { var (host, basePath, scheme) = GetUrlComponents(httpRequest); swagger.Servers = new List { new OpenApiServer {Url = $"{scheme}://{host}{basePath}"} }; }); c.RouteTemplate = "swagger/{documentName}/swagger.json"; }); applicationBuilder.UseSwaggerUI(c => { c.SwaggerEndpoint("v1/swagger.json", "NetworkResurrector API"); c.RoutePrefix = $"swagger"; }); return applicationBuilder; } private static (string host, string basePath, string scheme) GetUrlComponents(HttpRequest request) { var host = ExtractHost(request); var basePath = ExtractBasePath(request); var scheme = ExtractScheme(request); return (host, basePath, scheme); } private static string ExtractHost(HttpRequest request) { if (request.Headers.ContainsKey("X-Forwarded-Host")) return request.Headers["X-Forwarded-Host"].First(); return request.Host.Value; } private static string ExtractBasePath(HttpRequest request) { if (request.Headers.ContainsKey("X-Forwarded-PathBase")) return request.Headers["X-Forwarded-PathBase"].First(); return string.Empty; } private static string ExtractScheme(HttpRequest request) { return request.Headers["X-Forwarded-Proto"].FirstOrDefault() ?? request.Scheme; } } }