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

查看:107
本文介绍了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.如果输入以下内容,则我的Web应用程序将按预期工作:

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终止反向代理.这意味着在客户端和代理服务器之间建立了安全的流量.代理服务器解密请求,然后通过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-Proto HTTP标头.

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-ProtoX-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.

我的故事

上面的代码看起来与Microsoft建议的代码不同.如果我们看一下文档,它们的代码看起来会短一些:

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

在查看了ForwardedHeadersOptions的KnownNetworksKnownProxies集合,或者将docker网络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:对于那些在负载均衡器(例如Amazon Load Balancer或ELB)上设置SSL/TLS终止的用户不要在nginx配置中设置标头X-Forwarded-Proto.这将覆盖来自负载平衡到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天全站免登陆