首页 > 解决方案 > 当原始请求是 HTTPS 时,AspNetCore.WsFederation 将登录-wsfed 重定向到 HTTP

问题描述

上下文是托管在端口 HTTP 上的 Docker 容器中的 aspnetcore 2.1 网站,以及使用仅公开 HTTPS 443 的 Nginx 反向代理。

该网站通过 HTTPS 从外部访问,它重定向到 HTTPS 上的 STS 网站,该网站重定向到 HTTPS 上的 /signin-wsfed。

但是,来自 /signin-wsfed的响应位置是 HTTP。

这是请求:

POST https://core-mydocker.####/signin-wsfed HTTP/1.1
Accept: image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/xaml+xml, application/x-ms-xbap, */*
Referer: https://sts-mydocker.####/Pages/Email/Default.aspx?wtrealm=https%3a%2f%2fcore-mydocker.####%2f&wa=wsignin1.0&wreply=https%3a%2f%2fcore-mydocker.####%2fsignin-wsfed&wctx=#####
Accept-Language: fr-FR,fr;q=0.8,en-GB;q=0.6,en;q=0.4,ja;q=0.2
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.2; WOW64; Trident/7.0)
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
Host: core-mydocker.####
Content-Length: 10612
Connection: Keep-Alive
Cache-Control: no-cache

和回应:

HTTP/1.1 302 Found
Server: nginx/1.12.2
Date: Thu, 21 Feb 2019 09:39:34 GMT
Content-Length: 0
Connection: keep-alive
Cache-Control: no-cache
Pragma: no-cache
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Location: http://core-mydocker.####/Authenticate
Set-Cookie: .AspNetCore.Correlation.WsFederation.######=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; HTTPOnly; Securesignin-wsfed; httponly
Set-Cookie: FedAuth=#######=/; HTTPOnly; Secure; httponly
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: https://mydocker.####

HTTP 从外部无法访问,这会引发错误。

考虑到早期请求(wtrealm、wreply、...)中的每个参数都是 HTTPS,Microsoft.AspNetCore.Authentication.WsFederation 如何确定响应位置?

标签: c#dockerasp.net-corews-federation

解决方案


我可以找到这个问题的解决方案,它与转发标题有关。

碰巧配置Nginx如下:

proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto $scheme;

然后按如下方式配置 ASPNET Core:

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

是不足够的。此帖子中提供的解决方案proto headers not working

默认情况下,KnownNetworks 集合仅处理 127.0.0.1。在每个容器都在一个单独的 IP 上的 Docker 环境中,这肯定是不正确的,因此转发的标头将被忽略。

正如经过验证的答案所建议的,将代码更改为以下内容,解决了问题:

var forwardingOptions = new ForwardedHeadersOptions()
{
    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
};
forwardingOptions.KnownNetworks.Clear(); //its loopback by default
forwardingOptions.KnownProxies.Clear();
app.UseForwardedHeaders(forwardingOptions);

推荐阅读