.NET 8应用在NGINX反向代理下集成Google身份验证报错
.NET 8 反向代理环境下Google身份验证redirect_uri_mismatch问题
问题概述
我在NGINX反向代理后的.NET 8 Web应用中添加Google身份验证功能时遇到了问题:
- 应用是简单CRUD服务,代理端通过Let's Encrypt证书实现HTTPS终止,代理与应用之间使用明文HTTP通信
- 已配置反向代理的X-Forwarded-*头部,此前应用返回的图片等资源链接均为
https://*格式,确认代理头部配置有效 - 使用Microsoft Identity库实现Google登录,Google端已配置正确的Client ID、Client Secret,且将
https://www.example.com/signin-google加入回调允许列表 - 登录流程初始跳转Google正常,用户选择账号后回调到
/signin-google时,应用向Google请求用户信息被拒绝,错误为Bad Request和redirect_uri_mismatch - 纯HTTP环境+Google开发模式下功能正常,仅在HTTPS代理环境出现该问题
复现代码(VS模板简化版)
var builder = WebApplication.CreateBuilder(args); var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found."); builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(connectionString)); builder.Services.AddDatabaseDeveloperPageExceptionFilter(); builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores<ApplicationDbContext>(); builder.Services .AddAuthentication() .AddGoogle(options => { options.ClientId = "deleted"; options.ClientSecret = "deleted"; }); // 测试用配置,允许所有代理 builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.All; options.ForwardLimit = null; options.KnownProxies.Clear(); options.KnownNetworks.Clear(); }); var app = builder.Build(); app.UseForwardedHeaders(); // 登录跳转接口,正常显示Google登录页面 app.MapGet("login", () => { var authenticationProperties = new AuthenticationProperties { RedirectUri = "ok" }; return Results.Challenge(authenticationProperties, [GoogleDefaults.AuthenticationScheme]); }); // 从未触发,回调后直接抛出.NET异常 app.MapGet("ok", () => "ok"); app.Run();
异常页面显示Google返回redirect_uri_mismatch错误,地址栏显示https://www.example.com/signin-google?state=xxx
NGINX代理配置
location / 下的头部配置:
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
请求头确认上述头部已正确设置,Host也为正确的域名
额外验证实验
为排除代理问题,编写了简单测试应用:
var builder = WebApplication.CreateBuilder(args); builder.Services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.All; options.ForwardLimit = null; options.KnownProxies.Clear(); options.KnownNetworks.Clear(); }); var app = builder.Build(); // 打印UseForwardedHeaders前后的IsHttps状态 app.Use((ctx, next) => { Console.WriteLine(ctx.Request.IsHttps); return next(ctx); }); app.UseForwardedHeaders(); app.Use((ctx, next) => { Console.WriteLine(ctx.Request.IsHttps); return next(ctx); }); app.MapGet("/", () => "Works!"); app.Run();
输出结果:
http://localhost:False, Falsehttps://localhost:True, Truehttps://example.com(代理后):False, True
确认UseForwardedHeaders()生效后Request.IsHttps已变为True,但Google身份验证库似乎未使用该信息生成正确的HTTPS回调URI
内容的提问来源于stack exchange,提问作者Gytis Murauskas
相关产品推荐
相关产品推荐

