Swashbuckle 在反向代理後面執行時使用埠 80 進行 https
我有一個用 swagger/swashbuckle 記錄的 .net 核心 api。
在 localhost 上的 url https://localhost:44390/ 上執行 swagger ui 時,“試試看”工作正常。
我們在 Azure 的應用服務中擁有相同的解決方案,其中 Azure Front Door 充當反向代理。Front Door 僅接受 https 流量並且僅轉發 https 流量。前門域是 widget.example.com,應用服務是 widget-test-app.azurewebsites.net。在 Azure 中使用 url https://widget.example.com/api/index.html執行 swagger ui 時,與在 localhost 中執行相比有兩個不同之處:
- swagger ui 顯示了一個 Servers 標題和一個下拉列表
- swagger ui 將伺服器 url 顯示為https://widget.example.com:80
我使用以下程式碼在 api 中添加了一個端點
return $"Host {HttpContext.Request.Host.Host} Port {HttpContext.Request.Host.Port} Https {HttpContext.Request.IsHttps}";當請求https://widget.example.com/api/v1/test/url它返回
主機 widget-test-app.azurewebsites.net 埠 Https True
這完全沒問題,因為 Front Door 正在更改主機標頭。不過,埠是空的。
摘要:Swagger ui 在 Servers -dropdown 中顯示正確的域,但埠號錯誤。如果它是 80 或 443,我怎樣才能讓它省略埠號,或者正確添加它?
**更新:**問題出在 swagger.json 文件中,反向代理後麵包含一個servers元素
"servers": [{ "url": "https://widget.example.com:80" }]啟動.ConfigureServices
services.AddApiVersioning(options => { options.Conventions.Add(new VersionByNamespaceConvention()); }); services.AddVersionedApiExplorer(o => { o.GroupNameFormat = "'v'VVV"; o.SubstituteApiVersionInUrl = true; }); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "Widget backend v1", Version = "v1" }); c.SwaggerDoc("v2", new OpenApiInfo { Title = "Widget backend v2", Version = "v2" }); c.EnableAnnotations(); c.AddEnumsWithValuesFixFilters(); var xmlFile = $ "{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); c.IncludeXmlComments(xmlPath); });啟動.配置
app.UseSwagger(options => { options.RouteTemplate = "/api/swagger/{documentname}/swagger.json"; }); app.UseSwaggerUI(options => { foreach(var description in provider.ApiVersionDescriptions) { options.SwaggerEndpoint($ "/api/swagger/{description.GroupName}/swagger.json", "widget backend " + description.GroupName); } options.RoutePrefix = "api"; });
為了解決這個問題,我清除了伺服器列表。這是我的程式碼:
app.UseSwagger(options => { options.RouteTemplate = "/api/swagger/{documentname}/swagger.json"; options.PreSerializeFilters.Add((swagger, httpReq) => { //Clear servers -element in swagger.json because it got the wrong port when hosted behind reverse proxy swagger.Servers.Clear(); }); });
解決方案(好的,我的 - 解決方案 :))是在 Startup 中配置轉發標頭。
services.Configure<ForwardHeadersOptions>(options => { options.ForwardHeaders = ForwardHeaders.All; // For, Proto and Host options.KnownNetworks.Clear(); options.KnownProxies.Clear(); });這樣做,應用程序中的任何 URL 生成(在反向代理之後)都應該尊重埠轉發值。根據文件,應指定已知網路(取自文件):
僅允許受信任的代理和網路轉發標頭。否則,IP 欺騙攻擊是可能的。
有關詳細資訊,請參閱ASP.NET 文件。