Search code examples
.netlinuxoauth-2.0reverse-proxykestrel-http-server

.NET 6 OAuth authentication behind reverse proxy: wrong redirect url on challenge


I'm struggling to enable OAuth2 on a .net 6 razor pages project hosted on linux, using Apache as reverse proxy.

I got an issue about the "redirect_uri" on my OAuth challenge: the URI I get is the local, not the one exposed through the reverse-proxy. Basically: i reach my webapp accessing to "login.domain.com" (where apache forwards my requests on the local kestrel instance). But once i challenge the remote login provider, i get

&redirect_uri=http://127.0.0.1:5000/discord-signin

The headers my reverse proxy fowards seems to be correct:

2021-12-19 16:11:44.487 +01:00 [WRN] Header: Accept: ["text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Connection: ["keep-alive"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Host: ["127.0.0.1:5000"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: User-Agent: ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Accept-Encoding: ["gzip, deflate, br"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Accept-Language: ["en-US,en;q=0.9,it;q=0.8,de;q=0.7"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Cache-Control: ["max-age=0"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Content-Type: ["application/x-www-form-urlencoded"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Cookie: ["_ga=GA1.2.542637492.1636097135; .AspNetCore.Antiforgery.DTVEdTt8EGg=CfDJ8MlMA29MyfZGjp9AYHEkO4mfg3bwuzIArowPu6tG3DH6IZfzcsAfWAHKHoMi7NeY_dakBIxSHpBv-l_vrIZER2oU06TRVh9A3shL_H6j6gpj_frjZwyNF8qMNpVws7UCg7GGtDZMQIg92GuFtzmo5S0"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Origin: ["login.domain.com"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Referer: ["https://discord.ivao.it/accounts"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Upgrade-Insecure-Requests: ["1"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Content-Length: ["182"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: sec-ch-ua: ["\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Microsoft Edge\";v=\"96\""]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: sec-ch-ua-mobile: ["?0"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: sec-ch-ua-platform: ["\"Windows\""]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Sec-Fetch-Site: ["same-origin"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Sec-Fetch-Mode: ["navigate"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Sec-Fetch-User: ["?1"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: Sec-Fetch-Dest: ["document"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: X-Forwarded-Host: ["login.domain.com"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: X-Forwarded-Server: ["login.domain.com"]
2021-12-19 16:11:44.487 +01:00 [WRN] Header: X-Original-For: ["127.0.0.1:49194"]

And here it is how i configured my auth:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = DiscordAuthenticationDefaults.AuthenticationScheme;
})
.AddCookie(opt =>
{
    opt.LoginPath = "/discordauth/signedin";
})
.AddDiscord(opt =>
{
    opt.ClientId = "771681863952891944";
    opt.ClientSecret = "vBvBa3OLkydqkMalLQLHxjGmluqiqflC";
});

I also enabled the forwarded header middleware as prescribed by MS in the process for the Linux deployment

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

app.UseAuthorization();
app.UseAuthentication();

So, what am i missing? Why my challenge request generates the redirect_uri pointing to the local "localhost:5000" instead of the frontend login.domain.com?

Thanks in advance for the help


Solution

  • Ok guys. I think i solved my error (because it is, my bad...).

    Since my reverse-proxy sends my 3 headers about the forward:

    2021-12-19 16:11:44.487 +01:00 [WRN] Header: X-Forwarded-Host: ["login.domain.com"]
    2021-12-19 16:11:44.487 +01:00 [WRN] Header: X-Forwarded-Server: ["login.domain.com"]
    2021-12-19 16:11:44.487 +01:00 [WRN] Header: X-Original-For: ["127.0.0.1:49194"]
    

    I was basically telling .net to process the wrong ones with my config:

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

    In this case httpContext.Request.Host was not overriden by the ForwardedHeadersMiddleware since i have forgot to tell it to process also the Host header "X-Forwarded-Host".

    This solves my problem:

    var forwardedHeadersOptions = new ForwardedHeadersOptions
    {
        ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost,
    };