OData / WebApi

OData Web API: A server library built upon ODataLib and WebApi
https://docs.microsoft.com/odata
Other
857 stars 473 forks source link

How to force all links to use HTTPS instead of HTTP when using SSL Offload #1981

Open norcino opened 4 years ago

norcino commented 4 years ago

We use ODATA (.net core) in servers behind a load balance where we do SSL Offload, this means that all ODATA API are hit with an http:// url. I need to conditionally be able to force all urls to use https://. How can I do it?

I went trough the source code but I could not find any hint on how to do what I need.

For now I wrote a simple middleware as shown below but this is an hack I don't like, and can have unforeseen side effects.

// Middleware used to simulate an https request when behing a load balancer with SSL offloade
app.Use(async (context, next) =>
{
    if (context.Request.Headers.ContainsKey("X-Forwarded-Proto"))
    {
        // The request schema is used by OData to generate all links like, Metadata, Next, GetById and so on
        context.Request.Scheme = "https";
    }
    await next();
});
rajAshu commented 4 years ago

We are also facing the same issue, Due to load balancer SSL offloading, URL generated in server responses are HTTP instead of HTTPS

joaopgrassi commented 4 years ago

I managed to get this to work (our OData api is inside a k8s cluster, with nginx/ocelot). Basically I used the instructions from the docs here: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.1#scenarios-and-use-cases

In your code you need to enable the middleware:

ConfigureServices:

services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders =
        ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost;
});

Configure (before anything else)

app.UseForwardedHeaders();

You just need then to configure in your load balancer/reverse proxy to forward the X-Forwarded-Proto and X-Forwarded-Host. The middleware will do the rest.

UncleFirefox commented 3 years ago

Hey guys, I tried to do what you just described but I keep getting in "@odata.context" the same internal url that the reverse proxy uses. Apart from the lines above, did you have to do anything else @joaopgrassi ?

Thanks!

joaopgrassi commented 3 years ago

@UncleFirefox not really. In Configure services I only have the lines I mentioned above. In Configure we have some custom stuff because we have a prefix in our urls.. but I don't think it's relevant to you.

Are you sure you are forwarding the headers from your reverse proxy? You can check here: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0

UncleFirefox commented 3 years ago

Yeah, I did all the code says but it does not give me the url that originated the request. Instead of that, I get an IP. Maybe I'm a little lost on how the context field is generated? I'm pretty sure the proper url is in the x-forwarded-host header as I put traces all over the code... Without the context field properly set I will be unable to consume an odata feed from excel for example...

My problem is very similar to yours in the sense that I'm also behind reverse proxy, k8s cluster etc. What did you do to have the proper urls being detected by odata?

joaopgrassi commented 3 years ago

All of our services in the k8s cluster, including the OData ones are not accessible from the outside. The only way to reach them is via our API Gateway, which for now is just a API using Ocelot. The Gateway API has a ingress controller (nginx). With Ocelot there's a way to intercept the requests before it gets sent to the downstream service. In that moment, we add the headers.

I'll try to see if there's anything special in our ingress controller during the weekend, if I find I will post here. Is your OData service exposed from the cluster?

Edit: Did you set these in your ngix controller? Do you have the headers in your OData app? https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-5.0#nginx-configuration https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0#configure-nginx