如何让Swagger UI将端口443与Swashbuckle一起使用?

时间:2016-04-14 13:43:13

标签: swagger 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会列出我的网络方法,但是当我点击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。

2 个答案:

答案 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/v1swagger/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