反向代理后面的 .NET 6 OAuth 身份验证:质询时重定向 url 错误
Posted
技术标签:
【中文标题】反向代理后面的 .NET 6 OAuth 身份验证:质询时重定向 url 错误【英文标题】:.NET 6 OAuth authentication behind reverse proxy: wrong redirect url on challenge 【发布时间】:2022-01-21 12:49:16 【问题描述】:我正在努力在 Linux 上托管的 .net 6 razor pages 项目上启用 OAuth2,使用 Apache 作为反向代理。
我在 OAuth 质询中遇到了关于“redirect_uri”的问题:我获得的 URI 是本地的,而不是通过反向代理公开的。 基本上:我访问了我的 webapp 访问“login.domain.com”(apache 在本地 kestrel 实例上转发我的请求)。但是一旦我挑战远程登录提供程序,我就会得到
&redirect_uri=http://127.0.0.1:5000/discord-signin
我的反向代理转发的标头似乎是正确的:
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"]
这就是我配置身份验证的方式:
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";
);
我还在 Linux 部署过程中启用了 MS 规定的转发头中间件
app.UseCookiePolicy();
app.UseRouting();
app.UseForwardedHeaders(new ForwardedHeadersOptions
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
);
app.UseAuthorization();
app.UseAuthentication();
那么,我错过了什么?为什么我的质询请求会生成指向本地“localhost:5000”而不是前端 login.domain.com 的 redirect_uri?
提前感谢您的帮助
【问题讨论】:
【参考方案1】:好的,伙计们。我想我解决了我的错误(因为它是我的错……)。
由于我的反向代理发送了我的 3 个关于正向的标头:
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"]
我基本上是在告诉 .net 用我的配置处理错误的:
app.UseForwardedHeaders(new ForwardedHeadersOptions
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
);
在这种情况下,httpContext.Request.Host 没有被 ForwardedHeadersMiddleware 覆盖,因为我忘记告诉它也处理 Host 标头“X-Forwarded-Host”。
这解决了我的问题:
var forwardedHeadersOptions = new ForwardedHeadersOptions
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost,
;
【讨论】:
以上是关于反向代理后面的 .NET 6 OAuth 身份验证:质询时重定向 url 错误的主要内容,如果未能解决你的问题,请参考以下文章
在反向代理后面使用 OAuth2 的 Spring Boot