Nginx Asp.Net核心Google身份验证
我的应用程序在谷歌计算引擎上运行。Nginx用作代理服务器。Nginx被配置为使用SSL。以下是/etc/nginx/sites available/default的内容:Nginx Asp.Net核心Google身份验证,nginx,asp.net-core,google-cloud-platform,google-sso,Nginx,Asp.net Core,Google Cloud Platform,Google Sso,我的应用程序在谷歌计算引擎上运行。Nginx用作代理服务器。Nginx被配置为使用SSL。以下是/etc/nginx/sites available/default的内容: server { listen 80 default_server; listen [::]:80 default_server; server_name mywebapp.com; return 301 https://$server_name$request_uri; } server {
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mywebapp.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
include snippets/ssl-mywebapp.com.conf;
include snippets/ssl-params.conf;
root /home/me/MyWebApp/wwwroot;
location /.well-known/ {
}
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
在Startup.cs中,我有:
app.UseGoogleAuthentication(new GoogleOptions()
{
ClientId = Configuration["Authentication:Google:ClientId"],
ClientSecret = Configuration["Authentication:Google:ClientSecret"],
});
现在在Google云平台中,我需要指定授权重定向URI。如果我输入以下内容,我的web应用程序将按预期工作:
http://mywebapp.com/signin-google
但是,如果使用https
,它将不起作用;浏览器显示以下错误:
The redirect URI in the request, http://mywebapp.com/signin-google, does
not match the ones authorized for the OAuth client.
在这种情况下,使用http作为授权重定向uri是否安全?如果我希望它是https,我需要什么配置 发生这种情况是因为运行在反向代理服务器后面的应用程序不知道最初的请求是通过HTTPS发出的 SSL/TLS终止代理 问题中描述的反向代理的配置称为SSL/TLS终止反向代理。这意味着在客户端和代理服务器之间建立安全通信。代理服务器解密请求,然后通过HTTP协议将其转发给应用程序 此配置的问题在于,其背后的应用程序不知道客户端通过HTTPS发送了请求。因此,当重定向到自身时,它使用
HttpContext.Request.Scheme
、HttpContext.Request.Host
和HttpContext.Request.Port
为重定向构建有效的URL
X-Forwarded-*HTTP头文件
这就是X-Forwarded-*
标题发挥作用的地方。为了让应用程序知道请求最初是通过HTTPS通过代理服务器发送的,我们必须将代理服务器配置为设置X-Forwarded-For
和X-Forwarded-Proto
HTTP头
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
好的,现在如果我们回到ASP.NET核心应用程序并查看传入的HTTP请求,我们将看到设置了X-Forwarded-*
头,但是重定向URL仍然使用HTTP方案
转发头中间件
基本上,该中间件将HttpContext.Request.Scheme
和HttpContext.Connection.RemoteIpAddress
覆盖到X-Forwarded-Proto
和X-Forwarded-For
头提供的值。为了实现这一点,让我们通过在Startup.Configure()
方法开头的某处添加以下行,将其添加到管道中
var forwardedHeadersOptions = new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
RequireHeaderSymmetry = false
};
forwardedHeadersOptions.KnownNetworks.Clear();
forwardedHeadersOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardedHeadersOptions);
这将最终使您的应用程序使用HTTPS方案构造有效的URL
我的故事
上面的代码看起来与微软的建议不同。如果我们看一下他们的代码,就会发现代码短了一点:
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
然而,这对我不起作用。根据下面的评论,我并不孤单
我已经为运行在Docker容器中的ASP.NET核心应用程序设置了一个nginx作为反向代理。在我把一切都放在Amazon负载平衡器(ELB)后面之后,事情变得更加复杂了
我首先遵循了文档中的建议,但它对我不起作用。我的应用程序中出现以下警告:
X-Forwarded-For和X-Forwarded-Proto之间的参数计数不匹配
然后我看了看我的X-Forwarded-*
头,发现它们的长度不同X-Forwarded-For
头包含2条记录(以逗号分隔的IP地址),而X-Forwarded-Proto
只有一条记录https
。这就是我如何将属性RequireHeaderSymmetry
设置为false
我去掉了“参数计数…”警告消息,但紧接着我又遇到了另一条奇怪的调试消息:
未知代理:172.17.0.6:44624
在查看了的源代码之后,我终于发现我必须清理KnownNetworks
和KnownProxies
的ForwardedHeadersOptions
集合,或者将我的docker网络172.17.0.1/16
添加到已知网络列表中。就在那之后,我终于让它工作了
PS:对于在负载平衡器(如Amazon负载平衡器或ELB)上设置SSL/TLS终端的用户,不要在nginx配置中设置头
X-Forwarded-Proto
。这将覆盖从负载平衡到http
方案的正确https
值,重定向url将是错误的。我还没有找到如何将nginx中使用的scheme追加到头部,而不是覆盖它 谢谢你。我最近将一个项目从Core1.0迁移到了2.0,旧项目中的定制中间件kludge不再起作用(这是对context.Request的简单头检查,它根据转发的头执行context.Request.Scheme=“https”
)。您的解决方案使我们的OAuth提供程序再次运行。我确认,从当前版本开始,可以在此处找到:仍然检查KnownNetworks和KnownProxies,因此仍然需要以下代码:forwardedHeadersOptions.KnownNetworks.Clear();forwardedHeadersOptions.KnownProxies.Clear();这为我节省了大量的时间(在花费了大量的时间之后)。从我的asp.net核心应用程序旁边的nginx侧车中删除转发的Proto,它位于ssl终止负载平衡器后面,通过帮助kestrel使用正确的方案编写URL,使外部登录工作正常@亚历克西,丹佛有一瓶啤酒等着你,如果你能来到这个世界的地方。