在反向代理后面运行时,使用Swashbuckle使用端口80进行https

问题描述

我有一个用swagger / swashbuckle记录的.net核心api。

在网址为https:// localhost:44390 /的localhost上运行swagger ui时,“尝试一下”工作正常。

我们在Azure的App服务中具有相同的解决方案,其中Azure前门充当反向代理。前门仅接受https流量,并且仅转发https流量。前门域是widget.example.com,应用程序服务是widget-test-app.azurewebsites.net。在使用URL https://widget.example.com/api/index.html在Azure中运行swagger ui时,与在localhost中运行相比有两个区别:

  1. 招摇的ui显示服务器标题和下拉列表
  2. 招摇的用户界面将服务器网址显示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

这完全可以,因为前门正在更改主机头。端口为空。

摘要:Swagger ui在“服务器”下拉列表中显示了正确的域,但端口号错误。我该如何删除端口号(如果是80或443)或正确添加端口号?

更新:问题出在swagger.json文件中,该文件位于反向代理后面,其中包含 servers 元素

"servers": [{
  "url": "https://widget.example.com:80"
}]

Startup.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);
});

Startup.Configure

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 spoofing 次攻击。

有关详细信息,请参阅 ASP.NET documentation