using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.OpenApi.Models; using System.Collections.Generic; using System.Linq; namespace IdentityServer.Api.Swagger { public static class SwaggerExtensions { public static IServiceCollection AddSwagger(this IServiceCollection services) { services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Identity Server API", Version = "v1" }); 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", "IdentityServer 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; } } }