如何让 Swagger UI 将端口 443 与 Swashbuckle 一起使用?
How do I get Swagger UI to use port 443 with Swashbuckle?
在我们的 运行 我们的 RESTful Web 服务的 QA 和 Prod 环境中,端口 80 未打开。所以目前当我尝试在 QA 中使用 Swagger UI 时,我收到这条消息并且它只是挂起:
fetching resource list: http://qa-server:80/product-catalog-api/swagger/docs/v1; Please wait.
我正在使用 Swashbuckle 配置 Swagger。我也在配置中更改了这一行,但它仍然不起作用。
// If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access
// the docs is taken as the default. If your API supports multiple schemes and you want to be explicit
// about them, you can use the "Schemes" option as shown below.
//
c.Schemes(new[] { "https" });
SSL 端口 443 是开放的所以我想去 Swagger UI 到 运行 就可以了。我可以手动将 http://qa-server:80/product-catalog-api/swagger/docs/v1
更改为 https://qa-server/product-catalog-api/swagger/docs/v1
,然后 Swagger 将列出我的 Web 方法,但是当我单击 Try it out!
时它会挂起 这是控制台的输出:SCRIPT5: Access is denied. File: swagger-ui-min-js, Line: 10, Column: 4300
编辑:
所以我一直在深入挖掘,已经走得更远了一点,但仍然不是我想去的地方。如果我在 Swagger index.html 文件上查看源代码,我可以看到问题:
window.swashbuckleConfig = {
rootUrl: 'http://qa-server:80/product-catalog-api',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('null'),
customScripts: arrayFrom(''),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
即使我以 https 导航到该站点并将 Swashbuckle 方案设置为 https,它仍将 rootUrl 生成为 http。我认为自从我使用 Swashbuckle 以来,我必须使用它来配置 index.html 因为我的代码中没有该文件,所以我猜 Swashbuckle 正在动态生成它。
我确实发现了我在更改 swagger.json 路径时遗漏了什么。它显然需要那里的端口号。因此,如果我导航到 swagger 索引页面并手动将 json 文件的路径更改为 https://qa-server:443/product-catalog-api/swagger/docs/v1
一切正常。所以现在我想我已经将问题归结为如何使用 Swashbuckle 更改 Swaggers index.html 中的 rootUrl。
编辑 2
好吧,我想我已经正确配置了 Swashbuckle,因为它在我们的开发服务器上正确生成了 index.html,但不是 qa 所以我想剩下的问题是由于环境或我的包的一些差异没有在 qa 中正确安装。
发展:
window.swashbuckleConfig = {
rootUrl: 'https://server-dev:443/product-catalog-api',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('null'),
customScripts: arrayFrom(''),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
质量检查:
window.swashbuckleConfig = {
rootUrl: 'http://qa-server:80/product-catalog-api',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('null'),
customScripts: arrayFrom(''),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
编辑 3
我们进行了测试以进一步隔离问题。我们的 QA 环境中有一个 A10 负载均衡器。我们为开发环境站了一个新的 A10 看看发生了什么,我们现在在开发中遇到了同样的问题。 A10 正在执行一些我们删除的 http header 操作以查看是否是问题所在,但仍然得到相同的结果。我相信通过服务器的设置方式,SSL 被卸载到 A10 并且盒子实际上 运行ning 我的代码正在获取 http。所以当 Swashbuckle 代码 运行s 时,它是 http 下的 运行ning 引起的问题。我想我需要一种方法来强制它始终为 https。
当 HTTP 请求到达 swagger/docs/v1
或 swagger/ui/index
时,Swashbuckle 会为您生成 Swagger 文档。如果您的请求通过 https
传入,那么它生成的默认 index.html 将包含 rootUrl
的 https://yourdomain:443/yourapiapplication
。同样,如果它通过 http
进入,则 rootUrl
将是 http://yourdomain:80/yourapiapplication
。鉴于这种情况,您的问题的主要候选者是缓存。您是否通过覆盖 SwaggerConfig.cs 中的默认 swagger 提供程序启用了 Swagger 文档的缓存?或者您的 QA 环境是否具有与您的开发环境不同的代理服务器或缓存设置?通过 HTTPS 向您的 QA 服务器发出新请求重新生成文档应该会在您的 index.html.
中生成正确的 rootUrl
我终于明白了!感谢 Sampada 和 strick01 帮助我隔离问题。我在 github 上找到了这篇文章,其中包含使用 Swashbuckle 强制 https 的解决方案:
https://github.com/domaindrivendev/Swashbuckle/issues/296
config
.EnableSwagger("docs/{apiVersion}",
c =>
{
...
c.RootUrl(ResolveBasePath);
...
})
.EnableSwaggerUi();
private static string ResolveBasePath(HttpRequestMessage message)
{
var virtualPathRoot = message.GetRequestContext().VirtualPathRoot;
var schemeAndHost = "https://" + message.RequestUri.Host;
return new Uri(new Uri(schemeAndHost, UriKind.Absolute), virtualPathRoot).AbsoluteUri;
}
在我们的 运行 我们的 RESTful Web 服务的 QA 和 Prod 环境中,端口 80 未打开。所以目前当我尝试在 QA 中使用 Swagger UI 时,我收到这条消息并且它只是挂起:
fetching resource list: http://qa-server:80/product-catalog-api/swagger/docs/v1; Please wait.
我正在使用 Swashbuckle 配置 Swagger。我也在配置中更改了这一行,但它仍然不起作用。
// If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access
// the docs is taken as the default. If your API supports multiple schemes and you want to be explicit
// about them, you can use the "Schemes" option as shown below.
//
c.Schemes(new[] { "https" });
SSL 端口 443 是开放的所以我想去 Swagger UI 到 运行 就可以了。我可以手动将 http://qa-server:80/product-catalog-api/swagger/docs/v1
更改为 https://qa-server/product-catalog-api/swagger/docs/v1
,然后 Swagger 将列出我的 Web 方法,但是当我单击 Try it out!
时它会挂起 这是控制台的输出:SCRIPT5: Access is denied. File: swagger-ui-min-js, Line: 10, Column: 4300
编辑:
所以我一直在深入挖掘,已经走得更远了一点,但仍然不是我想去的地方。如果我在 Swagger index.html 文件上查看源代码,我可以看到问题:
window.swashbuckleConfig = {
rootUrl: 'http://qa-server:80/product-catalog-api',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('null'),
customScripts: arrayFrom(''),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
即使我以 https 导航到该站点并将 Swashbuckle 方案设置为 https,它仍将 rootUrl 生成为 http。我认为自从我使用 Swashbuckle 以来,我必须使用它来配置 index.html 因为我的代码中没有该文件,所以我猜 Swashbuckle 正在动态生成它。
我确实发现了我在更改 swagger.json 路径时遗漏了什么。它显然需要那里的端口号。因此,如果我导航到 swagger 索引页面并手动将 json 文件的路径更改为 https://qa-server:443/product-catalog-api/swagger/docs/v1
一切正常。所以现在我想我已经将问题归结为如何使用 Swashbuckle 更改 Swaggers index.html 中的 rootUrl。
编辑 2
好吧,我想我已经正确配置了 Swashbuckle,因为它在我们的开发服务器上正确生成了 index.html,但不是 qa 所以我想剩下的问题是由于环境或我的包的一些差异没有在 qa 中正确安装。
发展:
window.swashbuckleConfig = {
rootUrl: 'https://server-dev:443/product-catalog-api',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('null'),
customScripts: arrayFrom(''),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
质量检查:
window.swashbuckleConfig = {
rootUrl: 'http://qa-server:80/product-catalog-api',
discoveryPaths: arrayFrom('swagger/docs/v1'),
booleanValues: arrayFrom('true|false'),
validatorUrl: stringOrNullFrom('null'),
customScripts: arrayFrom(''),
docExpansion: 'none',
oAuth2Enabled: ('false' == 'true'),
oAuth2ClientId: '',
oAuth2ClientSecret: '',
oAuth2Realm: '',
oAuth2AppName: '',
oAuth2ScopeSeperator: ' ',
oAuth2AdditionalQueryStringParams: JSON.parse('{}')
};
编辑 3
我们进行了测试以进一步隔离问题。我们的 QA 环境中有一个 A10 负载均衡器。我们为开发环境站了一个新的 A10 看看发生了什么,我们现在在开发中遇到了同样的问题。 A10 正在执行一些我们删除的 http header 操作以查看是否是问题所在,但仍然得到相同的结果。我相信通过服务器的设置方式,SSL 被卸载到 A10 并且盒子实际上 运行ning 我的代码正在获取 http。所以当 Swashbuckle 代码 运行s 时,它是 http 下的 运行ning 引起的问题。我想我需要一种方法来强制它始终为 https。
当 HTTP 请求到达 swagger/docs/v1
或 swagger/ui/index
时,Swashbuckle 会为您生成 Swagger 文档。如果您的请求通过 https
传入,那么它生成的默认 index.html 将包含 rootUrl
的 https://yourdomain:443/yourapiapplication
。同样,如果它通过 http
进入,则 rootUrl
将是 http://yourdomain:80/yourapiapplication
。鉴于这种情况,您的问题的主要候选者是缓存。您是否通过覆盖 SwaggerConfig.cs 中的默认 swagger 提供程序启用了 Swagger 文档的缓存?或者您的 QA 环境是否具有与您的开发环境不同的代理服务器或缓存设置?通过 HTTPS 向您的 QA 服务器发出新请求重新生成文档应该会在您的 index.html.
rootUrl
我终于明白了!感谢 Sampada 和 strick01 帮助我隔离问题。我在 github 上找到了这篇文章,其中包含使用 Swashbuckle 强制 https 的解决方案:
https://github.com/domaindrivendev/Swashbuckle/issues/296
config
.EnableSwagger("docs/{apiVersion}",
c =>
{
...
c.RootUrl(ResolveBasePath);
...
})
.EnableSwaggerUi();
private static string ResolveBasePath(HttpRequestMessage message)
{
var virtualPathRoot = message.GetRequestContext().VirtualPathRoot;
var schemeAndHost = "https://" + message.RequestUri.Host;
return new Uri(new Uri(schemeAndHost, UriKind.Absolute), virtualPathRoot).AbsoluteUri;
}