movio / bramble

A federated GraphQL API gateway
https://movio.github.io/bramble/
MIT License
497 stars 53 forks source link

Allowed headers does not reach sub service #212

Closed codedge closed 1 year ago

codedge commented 1 year ago

Hey 👋

We use bramble with the following config

{
        "services":
          [
            "http://service1/api/graphql",
            "http://service2/api/graphql"
          ],
        "gateway-port": 8082,
        "private-port": 8083,
        "metrics-port": 9009,
        "log-level": "info",
        "poll-interval": "5s",
        "max-requests-per-query": 50,
        "plugins": [
          {
            "name": "cors",
            "config": {
              "allowed-origins": ["*.domain.net"],
              "allowed-headers": ["*"],
              "allow-credentials": true,
              "max-age": 3600
            }
          }
        ]
}

allowing all headers to be passed through. Unfortunately, the authorization header, on which we depend on in our services, is not being passed through and gets eaten by bramble. Neither by setting "allowed-headers": ["*"] or "allowed-headers": ["authorization"] the header (with the JWT) is passed through.

This does not even seem to be a problem of the CORS plugin itself, but already Bramble without any plugin would not forward the authorization header to any service behind.

The same happens when using the playground, which also offer the possibility to add headers to your request.

2023-06-08_222511

While debugging the client a bit more, I came across the GetOutgoingRequestHeadersFromContext which just returns nil no matter which header has been specified in the playground.

Any ideas or recommendations how to set individual, in our case authorization, headers?

codedge commented 1 year ago

In the meantime I wrote a small plugin that just takes the incoming header and add it via AddOutgoingRequestsHeaderToContext to the request to the services.

Maybe that is the way to go. Would be good to know, what you guys think.

pkqk commented 1 year ago

Hi @codedge, I think you're confusing the meaning of that option. The allowed-headers option to the cors plugin is used just to pass that value to the cors middleware. That then lets the cors preflight requests indicate that the browser is allowed to send those headers to the gateway. For example our webapp is served on a different domain to the graphql gateway, so we need cors settings to allow it to operate.

For authentication, we have a more complicated auth plugin that takes the authorization header and then using AddOutgoingRequestsHeaderToContext adds relevant headers to the downstream requests. We do authentication/authorization at the gateway level, leaving our downstream services to just trust the gateway and if necessary they check a few headers we've agreed upon for information from the authorization.

Your plugin approach is the right thing to do in this case, if you want the downstream services to handle auth.

codedge commented 1 year ago

Your plugin approach is the right thing to do in this case, if you want the downstream services to handle auth.

Thank you confirming this.