在我们运行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会列出我的网络方法,但是当我点击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,所以我猜其余的问题是由于环境有些不同或我的包没有' t正确安装在qa中。
DEV:
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('{}')
};
QA:
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
我们做了一个测试,以进一步隔离问题。我们的质量保证环境中有一个A10负载均衡器。我们为开发环境设置了一个新的A10,看看发生了什么,我们现在在开发中遇到了同样的问题。 A10正在做一些我们删除的http标头操作,看看是不是问题,但仍然得到同样的东西。我相信服务器的设置方式,SSL正在卸载到A10,实际运行我的代码的盒子正在获取http。因此,当Swashbuckle代码运行时,它在http下运行导致问题。我想我需要一种方法来强制它始终是https。
答案 0 :(得分:11)
我终于明白了!感谢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;
}
答案 1 :(得分:2)
当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
。