当 运行 落后于反向代理时,Swashbuckle 将端口 80 用于 https
Swashbuckle using port 80 for https when run behind reverse proxy
我有一个 .net 核心 api 记录在案 swagger/swashbuckle。
当 运行 在 url https://localhost:44390/ 上的本地主机上大摇大摆 ui 时,“试用”效果很好。
我们在 Azure 的应用服务中有相同的解决方案,其中 Azure Front Door 充当反向代理。 Front Door 只接受 https 流量并且只转发 https 流量。前门域名为 widget.example.com,应用服务为 widget-test-app.azurewebsites.net。当 运行 Azure 中的 swagger ui 使用 url https://widget.example.com/api/index.html 与本地主机中的 运行 相比有两个区别:
- 大摇大摆的 ui 正在显示服务器标题和下拉列表
- 大摇大摆 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它returns
Host widget-test-app.azurewebsites.net Port Https True
这完全没问题,因为 Front door 正在更换主机 header。不过端口是空的。
摘要: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.
中配置 forward headers
services.Configure<ForwardHeadersOptions>(options =>
{
options.ForwardHeaders = ForwardHeaders.All; // For, Proto and Host
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
这样做,应用程序中的任何 URL 代(在反向代理之后)应该 尊重 port-forwarding 值。根据文档,应指定已知网络(取自文档):
Only allow trusted proxies and networks to forward headers. Otherwise, IP spoofing attacks are possible.
有关详细信息,请参阅 ASP.NET documentation。
我有一个 .net 核心 api 记录在案 swagger/swashbuckle。
当 运行 在 url https://localhost:44390/ 上的本地主机上大摇大摆 ui 时,“试用”效果很好。
我们在 Azure 的应用服务中有相同的解决方案,其中 Azure Front Door 充当反向代理。 Front Door 只接受 https 流量并且只转发 https 流量。前门域名为 widget.example.com,应用服务为 widget-test-app.azurewebsites.net。当 运行 Azure 中的 swagger ui 使用 url https://widget.example.com/api/index.html 与本地主机中的 运行 相比有两个区别:
- 大摇大摆的 ui 正在显示服务器标题和下拉列表
- 大摇大摆 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它returns
Host widget-test-app.azurewebsites.net Port Https True
这完全没问题,因为 Front door 正在更换主机 header。不过端口是空的。
摘要: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.
中配置 forward headersservices.Configure<ForwardHeadersOptions>(options =>
{
options.ForwardHeaders = ForwardHeaders.All; // For, Proto and Host
options.KnownNetworks.Clear();
options.KnownProxies.Clear();
});
这样做,应用程序中的任何 URL 代(在反向代理之后)应该 尊重 port-forwarding 值。根据文档,应指定已知网络(取自文档):
Only allow trusted proxies and networks to forward headers. Otherwise, IP spoofing attacks are possible.
有关详细信息,请参阅 ASP.NET documentation。