来自身份服务器 3 的外部登录(通过 ADFS)以 http 状态代码 504 响应

External login (via ADFS) from identity server3 responds with http status code 504

我从客户那里收到了用于在 identityserver3 中配置 WsFederationAuthentication 的联合元数据端点。

从开发人员机器上一切正常,比如身份服务器登录重定向到 adfs 登录页面,但是在将解决方案部署到 AWS elastic bean stalk(位于私有子网中)之后,我在尝试登录时收到 504 HTTP 状态代码通过外部 (ADFS) 登录。

我在postman中模拟了这个场景。我在开发人员机器中收到 302 响应,但请求在 AWS ec2 实例中永远不会结束(邮递员结果窗格显示 'Loading...')。

我能够从 AWS ec2 实例浏览联合元数据 URL 和 /adfs/ls 端点。

在 idnetity 服务器日志中,我可以看到以下日志,

External login requested for provider: adfs

Triggering challenge for external identity provider

HTTP Response

{
    "StatusCode": 401,
    "Headers": {
        "Content-Type": [
            "text/html"
        ],
        "Server": [
            "Microsoft-IIS/10.0"
        ],
        "Content-Length": [
            "0"
        ]
    },   
    "Body": ""
 }

在此之后,网关超时发生(通过 AWS 负载均衡器)。

根据 Microsoft.Owin.Security.WsFederation.WsFederationAuthenticationHandler.cs 中的代码,从 ApplyResponseChallengeAsync() 方法,重定向响应应在具有 adfs 登录页面 URL 的位置 header 生成。 但是,这并没有发生。

我在 HTTPError.Log 中看到以下错误。

GET
/identity/external?provider=adfs&signin=699036641a8b2b6ddccea61bc8c1f715 --
1 Connection_Abandoned_By_ReqQueue DefaultAppPool

我在事件查看器日志中没有看到与上述 HTTP 错误相关的任何事件。

我搜索了上述错误,但解决方案并未针对此问题产生任何好的结果。

我进一步使用进程监控工具进行了调查,比较了本地和 aws ec2 实例之间针对 identityserver 外部登录端点请求的 tcp 操作,然后我发现 TCP 断开连接操作在 AWS ec2 实例中的 TCP 连接之后立即发生,但在本地这个没有发生,而是建立了 TCP 通信并且 tcp 通信进行得很顺利。

进一步使用 wireshark 工具进行调查,然后我发现在 Client Hello 调用后 AWS ec2 实例中发生握手失败。然后我比较了本地机器使用的 TLS 版本和密码套件(来自 wireshark 日志),我发现本地机器使用 TLS 1.2 和密码套件的区别:TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)

并且 AWS ec2 实例使用 ADFS 服务器不支持的 TLS 1.0。因此无法建立tcp连接导致握手失败。

我按照这个 link https://docs.microsoft.com/en-us/officeonlineserver/enable-tls-1-1-and-tls-1-2-support-in-office-online-server#enable-strong-cryptography-in-net-framework-45-or-higher 使 .net framewrok 使用强加密。

此注册表更新后,能够通过身份服务器 3 登录页面从外部 idp (ADFS) 成功登录。