Burgyn / MMLib.SwaggerForOcelot

This repo contains swagger extension for ocelot.
MIT License
354 stars 94 forks source link

Getting 404 when running with KubernetesServiceDiscoveryProvider #257

Closed Prod0 closed 1 year ago

Prod0 commented 1 year ago

Same problem as this post: https://github.com/Burgyn/MMLib.SwaggerForOcelot/issues/251

Describe the bug When running a local ocelot.json it's working perfectly. With these settings:

{
    "Routes": [
        {
            "SwaggerKey": "multitenant",
            "DownstreamPathTemplate": "/api/{everything}",
            "DownstreamScheme": "https",
            "DownstreamHostAndPorts": [
                {
                    "Host": "localhost",
                    "Port": 5001
                }
            ],
            "UpstreamPathTemplate": "/multitenant/{everything}",
            "UpstreamHttpMethod": [  ],
            "RouteIsCaseSensitive": false,
            "AuthenticationOptions": {
                "AuthenticationProviderKey": "Admin",
                "AllowedScopes": []
            }
        }
    ],
    "GlobalConfiguration": {
        "BaseUrl": "https://localhost:5021",
         "ServiceDiscoveryProvider": { }
    },
    "SwaggerEndPoints":
    [
      {
        "Key": "multitenant",
        "Config": [
          {
            "Name": "Multitenant API",
            "Version": "v1", 
            "Url": "https://localhost:5001/api/swagger/docs/v1/swagger.json"
          }
        ]
      }
    ]
}

But when using these settings on kubernetes:

{
    "Routes": [
        {
            "SwaggerKey": "multitenant",
            "DownstreamPathTemplate": "/api/{everything}",
            "DownstreamScheme": "http", 
            "DownstreamHostAndPorts": [
                {
                    "Host": "URLKUBERNETES",
                    "Port": 80
                }
            ],
            "UpstreamPathTemplate": "/multitenant/{everything}",
            "UpstreamHttpMethod": [ "Options", "Head","Get", "Post" , "Put", "Patch", "Delete"],
            "RouteIsCaseSensitive": false,
            "DangerousAcceptAnyServerCertificateValidator": true,
            "AuthenticationOptions": {
                "AuthenticationProviderKey": "Admin",
                "AllowedScopes": []
            },
            "VirtualDirectory":"/api"
        }
    ],
    "GlobalConfiguration": {
        "BaseUrl": "BASEURL",
        "ServiceDiscoveryProvider": {
          "Namespace": "NAMESPACE",
          "Type": "kube"   
        }
    },
    "SwaggerEndPoints":
    [
      {
          "Key": "multitenant", 
          "Config": [
            {
              "Name": "Multitenant API",
              "Version": "v1",
              "Service": {
                "Name": "multitenant",
                "Path": "/swagger/docs/v1/swagger.json"
              }
            }
          ]
      }
    ]
}

I'm getting 404 for /swagger/index.html with a : Fetch error Not Found /api/swagger/docs/v1/multitenant

but when I actually route to /swagger/docs/v1/multitenant in Postman I get the swagger.json file perfectly.

The routing works on kuberentes, also seems like getting the swagger.json file from downstream service. For some reason the /swagger endpoint is still showing 404.

Expected behavior Same as with the first settings file, swagger should work.

I would really appreciate some help, thanks!

Burgyn commented 1 year ago

Hi @Prod0,

If you use it in Postman, your path is /swagger/docs/v1/multitenant (without /api). But in the Not Found message it is /api/swagger/docs/v1/multitenant (with /api).

Try to remove the "VirtualDirectory":"/api" parameter from the route definition.

Prod0 commented 1 year ago

I tried to remove this parameter, and I receive this error after in my Kibana log

Error Code: UnableToFindDownstreamRouteError Message: Failed to match Route configuration for upstream path: /swagger/docs/v1/multitenant, verb: GET. errors found in ResponderMiddleware. Setting error response for request path:/swagger/docs/v1/multitenant, request method: GET"

Also I forgot to mention that the multitenant service required authentication, it's not public opened, so even if config is correct I will get error 401, and gateway swagger doesn't have any possibility to authenticate and after to send the token to down stream API.

Also here there is the configuration of multitenant API

        app.UseSwagger(c =>
        {
            c.RouteTemplate = "api/swagger/docs/{documentName}/swagger.json";
        });
        app.UseSwaggerUI(options =>
        {
            options.RoutePrefix = "api/swagger";
            options.SwaggerEndpoint("/api/swagger/docs/v1/swagger.json", "Multitenant API");
        });
Burgyn commented 1 year ago

How is it possible that when you call it from Postman without /api you get the correct data even if you have api/swagger/docs/{documentName}/swagger.json configured in the downstream service?


Authorization. SwaggerUI calls Ocelot first, where the middleware calls the downstream service. So the call to the downstream service does not happen directly. If you need to add some headers for authorization, you can use

app.UseSwaggerForOcelotUI(opt => {
  opt.DownstreamSwaggerHeaders = new[]
  {
      new KeyValuePair<string, string>("Auth-Key", "AuthValue"),
  };
})
Prod0 commented 1 year ago

Ok my bad I was using this URL : api/multitenant/swagger/index.html ... in the postman, sorry for that.

the thing is that we dont call locally domain/api/swagger/docs/{documentName}/swagger.json but domain/api/multitenant/swagger/docs/v1/swagger.json

But regarding to the DownstreamHeaders, The error is that we cant find the upstream route if we can get from multitenant any error code that we could set some headers but we didnt reach this step we only asking gateway and it reply sorry url is not matching configuration also we run swagger : https://domain/swagger/index.html without api prefix where multitenant require api prefix

Prod0 commented 1 year ago

@Burgyn please

Burgyn commented 1 year ago

Hi, I'm sorry but I can't help you much. Can you please isolate this behavior into a demo example and provide it to me?

github-actions[bot] commented 1 year ago

Closing after 8 days of waiting for the additional info requested.

Prod0 commented 1 year ago

Hello @Burgyn, where can I send you the demo project, sorry for the delay.