With reference to #1717, I need some help about configuration of Swagger when using API behind a reverse proxy. In this case the reverse proxy should be IIS. But I also want to know if and what are the possible differences to take into account if I change the proxy server.
Right now I'm using this configuration:
```c#
public static void UseSwaggerWithConfiguration(this IApplicationBuilder app)
{
app.UseSwagger(config =>
{
config.PostProcess = (document, request) =>
{
if (request.Headers.ContainsKey("X-Forwarded-Host"))
{
document.Host = request.Headers["X-Forwarded-Host"].First();
// This line was commented because of there's no X-...-Path header on IIS...
//document.BasePath = request.Headers["X-External-Path"].First();
}
};
});
app.UseSwaggerUi3(config =>
{
config.OAuth2Client = new OAuth2ClientSettings
{
ClientId = "control-api-swagger",
ClientSecret = "1B746C9D-4E00-449C-B3F2-A17171B6B46E".ToSha256(),
AppName = $"{title} - Swagger"
};
config.TransformToExternalPath = (internalUiRoute, request) =>
{
// What should be done here?
var externalPath = request.Headers.ContainsKey("X-External-Path") ? request.Headers["X-External-Path"].First() : "";
return externalPath + internalUiRoute;
};
config.SwaggerRoutes.Add(new SwaggerUi3Route("v1.0", "/swagger/v1.0/swagger.json"));
});
}
```
And I'm getting this problem:

But, when used without proxy, everything works.
As @deepforest was suggesting in #1717:
Based on MDN, X-Forwarded-Host is a de-facto standard XFH header, identifying the original host, useful to determine which Host was originally used.
So based on @RSuter nginx conf file, you can replace X-External-Host with X-Forwarded-Host.
As for the X-External-Path, if you consider the X-Forwarded-Host to also contain the path: '/externalpath', then you can also omit X-External-Path, but then, it will be a bit "harder" to extract the path in the Startup.cs file, unless @RSuter will update the TransformToExternalPath config to accept only the Host, and do the magic inside.
What should I do to make it works?
I'm looking at SwaggerDocumentMiddleware. It looks like GenerateSwaggerAsync caches generated _swaggerJson document. The issue is that when an application is deployed behind a reverse-proxy, e.g. nginx, uses the PostProcess handler to override host/basePath properties and the application is also accessible from the internal network, then the cached JSON document works either from public or internal network. In other words, if somebody accesses (performs the first HTTP request) the application from the internal network, then it won't work from the public network and vice versa.
What if to store _swaggerJson in a sort of dictionary, e.g.
// pseudo code
class Key {
string host;
string basePath;
}
Dictionary<Key, Json> _cache;
?
This approach allows to workaround the issue without much refactoring.
@RicoSuter
@StasPerekrestov looks fine to me... so this would be needed if the swagger ui is exposed on two different urls?
@RicoSuter exactly. I'll prepare a pull request and create a separate issue.
Thanks.
@StasPerekrestov, @RicoSuter I'm having the same issue since about 3 months.
I'm still in beta development with my application and so I was waiting to open the issue.
The problem for me is that when I install my server application on our test server, if I open the API from localhost/..., then Swagger is not working anymore from the external IP of the server, because the reference on the BasePath is cached as localhost/.... The only solution is to reboot my server application.
Please review this PR: https://github.com/RicoSuter/NSwag/pull/2196
The PR has been merged, why is this still open?
Let's close...
Most helpful comment
@RicoSuter exactly. I'll prepare a pull request and create a separate issue.
Thanks.