Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.Net Core 2.0 - Azure Active Directory - NGinX reverse Proxy - HTTPS

I have a .NET Core 2.0 website, running on Linux, listening on port 5000, behind an NGinX reverse proxy, which is listening on port 80 and 442. NGinX is configured to redirect HTTP traffic to HTTPS, and handle all communication over HTTPS. The NGinx Reverse Proxy and Asp.Net Core app are within their own docker containers, on a shared network.

This setup is currently working as described.

However, I would now like to Authenticate my users against our Azure Active Directory. I have run into a problem and don't know where to go from here.

First, let me show you how I have most of this configured, and then I'll explain my error.

NGinx (nginx.conf)

worker_processes 2;

events { worker_connections 1024; }

http {
    sendfile on;

    upstream docker-dotnet {
        server mycomp_prod:5000;
    }

    server {
            listen 80;
            server_name sales.mycompany.com;
            return 301 https://$host$request_uri;
    }

    server {
        listen 443 ssl;
        server_name sales.mycompany.com;
        ssl_certificate     /etc/nginx/ssl/combined.crt;
        ssl_certificate_key /etc/nginx/ssl/salesmycompany.key;

        location / {
            proxy_pass         http://docker-dotnet;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }

}

Dotnet:Startup.cs ConfigureServices()

services.AddAuthentication(sharedOptions =>
{
     sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
     sharedOptions.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddAzureAd(options => Configuration.Bind("AzureAd", options))
.AddCookie();

Dotnet:Startup.cs Configure()

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();

Dotnet: appsettings.json

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "Domain": "mycompany.com",
    "TenantId": "my-tenant-id",
    "ClientId": "my-client-id",
    "CallbackPath": "/signin-oidc"
  },

In My Azure Active Directory Tentant

I have configured 2 "Reply URLs"

  • https://sales.mycompany.com/signin-oidc
  • https://sales.mycompany.com

Now for the error / My Question

When I hit the site, I sign in. Afterward signing in, and choosing whether or not to "Stay signed in", I'm taken to a page with an error.

enter image description here

You can see in the error, that the Reply Address that is attempting to be redirected to, is HTTP, not HTTPS. I think this is coming from the line in appsettings.json that says:

"CallbackPath": "/signin-oidc"

And since my .NET Core Site (via Kestrel on port 5000) is not on HTTPS, it's trying to load http://example.com/signin-oidc, instead of HTTPS. Remember that my .NET Core Site is behind an NGinX reverse Proxy, which is configured to handle traffic on 443.

Thank you,

like image 619
Captainlonate Avatar asked Mar 17 '18 20:03

Captainlonate


2 Answers

I saw this and was able to get it working: https://github.com/aspnet/Security/issues/1702

        var fordwardedHeaderOptions = new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        };
        fordwardedHeaderOptions.KnownNetworks.Clear();
        fordwardedHeaderOptions.KnownProxies.Clear();

        app.UseForwardedHeaders(fordwardedHeaderOptions);
like image 112
charlierlee Avatar answered Nov 17 '22 10:11

charlierlee


You should check out the documentation on Hosting on Linux.

Make sure you use UseForwardedHeaders in the middleware pipeline before UseAuthentication:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

app.UseAuthentication();

Nginx will assign a header for the protocol used before it forwarded the call to Kestrel (among other things). This middleware will then check those headers to set the right protocol.

like image 1
juunas Avatar answered Nov 17 '22 11:11

juunas