Asp.Net Core Google 身份验证 [英] Asp.Net Core Google authentication

查看:36
本文介绍了Asp.Net Core Google 身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用在 Google Compute Engine 上运行.Nginx 用作代理服务器.Nginx 被配置为使用 SSL.以下是/etc/nginx/sites-available/default 的内容:

My app runs on Google Compute Engine. Nginx used as a proxy server. Nginx was configured to use SSL. Below is the content of /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 {
    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 中,我有:

In Startup.cs I have:

app.UseGoogleAuthentication(new GoogleOptions()
{
    ClientId = Configuration["Authentication:Google:ClientId"],
    ClientSecret = Configuration["Authentication:Google:ClientSecret"],
});

现在在 Google Cloud Platform 中,我需要指定授权的重定向 URI.如果我输入以下内容,我的网络应用程序将按预期工作:

Now in Google Cloud Platform I need to specify Authorized redirect URIs. If I enter the following, my web app works as expected:

http://mywebapp.com/signin-google

但是,如果使用https,它将不起作用;浏览器显示以下错误:

But, it won't work if https is used; browser displays the following error:

The redirect URI in the request, http://mywebapp.com/signin-google, does
not match the ones authorized for the OAuth client.

在这种情况下,使用 http 作为授权重定向 uri 是否安全?如果我想要它是https,我需要什么配置?

In this case, is it safe to use http as authorized redirect uri? What configuration do I need if I want it to be https?

推荐答案

发生这种情况是因为在反向代理服务器后面运行的应用程序不知道最初请求来自 HTTPS.

This happens because your application which is running behind a reverse proxy server doesn't have any idea that originally request came over HTTPS.

SSL/TLS 终止代理

问题中描述的反向代理的配置称为SSL/TLS Termination反向代理.这意味着在客户端和代理服务器之间建立了安全流量.代理服务器解密请求,然后通过 HTTP 协议将其转发给应用程序.

The configuration of the reverse proxy described in the question is called SSL/TLS Termination reverse proxy. That means that secure traffic is established between a client and a proxy server. The proxy server decrypts a request and then forwards it to an application over HTTP protocol.

此配置的问题在于其背后的应用程序不知道客户端通过 HTTPS 发送请求.因此,在重定向到自身时,它使用 HttpContext.Request.SchemeHttpContext.Request.HostHttpContext.Request.Port 来构建用于重定向的有效 URL.

The issue with this configuration is that an application behind it is not aware that client sent request over HTTPS. So when it comes to redirect to itself it uses HttpContext.Request.Scheme, HttpContext.Request.Host and HttpContext.Request.Port to build a valid URL for redirect.

X-Forwarded-* HTTP 标头

这是 X-Forwarded-* 标头发挥作用的地方.为了让应用程序知道请求最初是通过 HTTPS 的代理服务器来的,我们必须配置代理服务器以设置 X-Forwarded-ForX-Forwarded-ProtoHTTP 标头.

This is where X-Forwarded-* headers come into play. To let the application know that request is originally coming through a proxy server over HTTPS we have to configure the proxy server to set X-Forwarded-For and X-Forwarded-Proto HTTP headers.

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 Core 应用程序并查看传入的 HTTP 请求,我们将看到两个 X-Forwarded-* 标头集,但是重定向 URL 仍然使用 HTTP方案.

OK, now if we get back to ASP.NET Core application and take a look at incoming HTTP request we will see both X-Forwarded-* headers set, however a redirect URL still uses HTTP scheme.

转发头中间件

基本上这个中间件将 HttpContext.Request.SchemeHttpContext.Connection.RemoteIpAddress 覆盖为 X-Forwarded-Proto 提供的值和 X-Forwarded-For 标头.为了实现这一点,让我们通过在 Startup.Configure() 方法的开头添加以下行来将其添加到管道中.

Basically this middleware overrides HttpContext.Request.Scheme and HttpContext.Connection.RemoteIpAddress to values which were provided by X-Forwarded-Proto and X-Forwarded-For headers appropriately. To make it happen let's add it to pipeline by adding the following line somewhere in the beginning of the Startup.Configure() method.

        var forwardedHeadersOptions = new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto,
            RequireHeaderSymmetry = false
        };
        forwardedHeadersOptions.KnownNetworks.Clear();
        forwardedHeadersOptions.KnownProxies.Clear();

        app.UseForwardedHeaders(forwardedHeadersOptions);

这最终将使您的应用程序使用 HTTPS 方案构建有效的 URL.

This should eventually make your application construct valid URLs with HTTPS scheme.

我的故事

上面的代码看起来与微软建议的不同.如果我们查看文档,他们的代码看起来会更短一些:

The code above looks different to what Microsoft suggests. If we take a look in documentation their code looks a bit shorter:

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

但是这对我不起作用.同样根据这个问题下的评论,我并不孤单.

However this didn't work for me. Also according to the comments under this issue I'm not alone.

我有一个 nginx 设置为在 Docker 容器中运行的 ASP.NET Core 应用程序的反向代理.在我将所有内容都放在 Amazon Load Balancer (ELB) 之后,情况变得更加复杂.

I have a nginx set up as reverse proxy for ASP.NET Core application running in Docker container. It became more complicated after I put everything behind Amazon Load Balancer (ELB).

我首先遵循了文档中的建议,但它对我不起作用.我的应用中收到以下警告:

I followed advice from the documentation first, but it didn't work for me. I have got the following warning in my app:

X-Forwarded-For 和 X-Forwarded-Proto 之间的参数计数不匹配

Parameter count mismatch between X-Forwarded-For and X-Forwarded-Proto

然后我查看了我的 X-Forwarded-* 标头并意识到它们的长度不同.X-Forwarded-For 头包含 2 条记录(以逗号分隔的 IP 地址),而 X-Forwarded-Proto 仅包含一条记录 https.这就是我如何将属性 RequireHeaderSymmetry 设置为 false.

Then I looked at my X-Forwarded-* headers and realized that they had different length. X-Forwarded-For header was containing 2 records (comma separated IP addresses), while X-Forwarded-Proto only one record https. This is how I came up to setting the property RequireHeaderSymmetry to false.

好吧,我摆脱了参数计数..."警告消息,但紧接着我又遇到了另一条奇怪的调试消息:

Well, I got rid of 'Parameter count...' warning message, but immediately after that I faced another odd debug message:

未知代理:172.17.0.6:44624

Unknown proxy: 172.17.0.6:44624

查看ForwardedHeadersMiddleware 我终于发现我必须清除 KnownNetworksKnownProxies 集合的 ForwardedHeadersOptions 或将我的 docker network 172.17.0.1/16 添加到已知网络列表中.在那之后,我终于让它工作了.

After looking into the source code of ForwardedHeadersMiddleware I have finally figured out that I have to either clean up both KnownNetworks and KnownProxies collections of the ForwardedHeadersOptions or add my docker network 172.17.0.1/16 to the list of known networks. Right after that I have finally got it working.

PS:对于那些在负载均衡器(例如亚马逊负载均衡器或 ELB)上设置 SSL/TLS 终止的人不要设置标头 X-Forwarded-Proto在 nginx 配置中.这将覆盖从负载平衡到 http 方案的正确 https 值,并且重定向 url 将是错误的.我还没有找到如何将 nginx 中使用的方案附加到标头而不是覆盖它.

PS: For those who sets up a SSL/TLS termination on load balancer (e.g. Amazon Load Balancer or ELB) DON'T set header X-Forwarded-Proto in nginx configuration. This will override correct https value which came from load balance to the http scheme and redirect url will be wrong. I have not found yet how to just append scheme used in nginx to the header instead of overriding it.

这篇关于Asp.Net Core Google 身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆