Asp.Net Core Google身份验证

syn*_*tic 7 nginx google-sso google-cloud-platform asp.net-core

我的应用在Google Compute Engine上运行.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 {
    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;
    }
}
Run Code Online (Sandbox Code Playgroud)

在Startup.cs我有:

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

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

http://mywebapp.com/signin-google
Run Code Online (Sandbox Code Playgroud)

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

The redirect URI in the request, http://mywebapp.com/signin-google, does
not match the ones authorized for the OAuth client.
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*ich 15

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

SSL/TLS终止代理

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

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

X-Forwarded-*HTTP标头

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

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;
}
Run Code Online (Sandbox Code Playgroud)

好的,现在如果我们回到ASP.NET Core应用程序并查看传入的HTTP请求,我们将看到两个X-Forwarded-*标头设置,但是重定向URL仍然使用HTTP方案.

转发的标头中间件

基本上,这个中间件会覆盖HttpContext.Request.Scheme和适当HttpContext.Connection.RemoteIpAddress提供的值X-Forwarded-ProtoX-Forwarded-For标头.为了实现它,我们通过在Startup.Configure()方法开头的某处添加以下行将其添加到管道中.

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

        app.UseForwardedHeaders(forwardedHeadersOptions);
Run Code Online (Sandbox Code Playgroud)

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

我的故事

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

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
     ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
Run Code Online (Sandbox Code Playgroud)

然而,这对我不起作用.根据这个问题的评论,我并不孤单.

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

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

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

然后我看了看我的X-Forwarded-*标题,发现它们有不同的长度.X-Forwarded-Forheader包含2条记录(逗号分隔的IP地址),而X-Forwarded-Proto只有一条记录https.这就是我设置属性的RequireHeaderSymmetry方法false.

好吧,我摆脱了'参数计数...'警告消息,但在此之后我又面临另一个奇怪的调试消息:

未知代理:172.17.0.6:44624

寻找到的源代码后ForwardedHeadersMiddleware我终于想通了,我不得不要么清理都KnownNetworksKnownProxies的收藏ForwardedHeadersOptions或添加我的搬运工网络172.17.0.1/16已知网络的列表.在那之后我终于开始工作了.

PS:对于在负载均衡器上设置SSL/TLS终止的用户(例如Amazon Load Balancer或ELB),请勿X-Forwarded-Proto在nginx配置中设置标头.这将覆盖https来自负载均衡到http方案的正确值,重定向url将是错误的.我还没有找到如何将nginx中使用的方案附加到标头而不是覆盖它.

  • 这节省了我大量的时间(在花费了大量时间之后)。从我的 asp.net core 应用程序旁边的 nginx sidecar 中删除 Forwarded-Proto(位于 ssl 终止负载均衡器后面),通过帮助 kestrel 使用正确的方案编写 url,使外部登录正常工作! (2认同)