ASP.NET Core反向代理场景下,是否应将UseForwardedHeaders()置于配置开关后?
嘿,这个问题我之前也碰到过!当ASP.NET Core跑在Nginx反向代理后面时,光加个基础的UseForwardedHeaders确实搞不定OpenID Connect的重定向URI问题,我来给你一步步解决:
第一步:补全ASP.NET Core的ForwardedHeaders配置
默认的配置没设置信任的代理主机,导致应用不认Nginx发过来的转发标头,自然拿不到正确的外部协议和域名。你得这么改:
app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto, // 这里填你的Nginx服务器IP,生产环境别用"*",指定具体IP更安全,本地测试可以加localhost AllowedHosts = { "192.168.1.100", "localhost" } });
⚠️ 重点:这个中间件一定要放在所有其他中间件前面——比如UseAuthentication、UseAuthorization甚至UseStaticFiles之前,不然转发的标头根本没机会被处理!
另外,别忘了在appsettings.json里把你的外部域名加到AllowedHosts里:
{ "AllowedHosts": "your-domain.com" }
第二步:让Nginx正确转发关键标头
Nginx这边得把真实的客户端IP和外部协议告诉ASP.NET Core,不然应用还是活在自己的小世界里。给你个参考配置:
# 先处理HTTP请求,重定向到HTTPS server { listen 80; server_name your-domain.com; return 301 https://$host$request_uri; } # HTTPS服务配置 server { listen 443 ssl; server_name your-domain.com; # 这里放你的SSL证书配置,比如cert和key路径,省略了哈 location / { proxy_pass http://localhost:5000; # 换成你的ASP.NET Core应用的地址端口 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; # 这俩是核心!告诉ASP.NET Core真实的客户端IP和外部协议 proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; } }
第三步:检查OpenID Connect的重定向URI配置
最后别忘了去你的OpenID Connect提供商(比如IdentityServer、Azure AD这些)那里,把重定向URI改成外部的完整地址,比如https://your-domain.com/signin-oidc,别用内部的http://localhost:5000/signin-oidc!
ASP.NET Core里的OIDC配置也要对应上,比如:
.AddOpenIdConnect("oidc", options => { options.Authority = "https://your-oidc-provider.com"; options.ClientId = "你的客户端ID"; options.ClientSecret = "你的客户端密钥"; options.CallbackPath = "/signin-oidc"; options.ResponseType = "code"; options.SaveTokens = true; options.GetClaimsFromUserInfoEndpoint = true; });
为啥默认配置不行?
默认的ForwardedHeadersOptions没设置AllowedHosts,相当于应用不信任任何外部的转发标头,Nginx发过来的X-Forwarded-Proto直接被忽略了,应用还是用内部的HTTP协议生成重定向URI,OIDC提供商一看这URI和你配置的不一样,直接给你拒了!
内容的提问来源于stack exchange,提问作者Thorarin

