iframe 为我的 Domino XPages 解决方案提供问题使用 Nginx 代理添加 JS 代码以使用 http 重定向而站点是 https

问题描述

如果这有点冗长,请提前抱歉 - 但我已经深入其中,所以我想提供我所知道的:-)

我有一个我们为客户提供的解决方案(在 IBM XPage 中开发),例如通过 iframe。我们现在已经开始看到 iframe 无法加载内容的问题。这发生在 Safari 和 Chrome 上的私人会话中。原因是这个小小的 Javascript 被注入到 iframe 页面标题中:

<head>
<script type="text/javascript">if(!navigator.cookieEnabled)window.location.href="http://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open\u0026assoc=49F1767931B31CD0C1258398007953C0\u0026type=1\u0026SessionID=77610D163AE659EC8C2C63FAF5E8BBA05E8C120D";
</script>
</head>

它自己的 iframe 看起来像这样:

<iframe src="https://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open&amp;assoc=02F2DD0AA9133BDCC1258618004A6B48&amp;type=1" width="100%" height="2100"></iframe>

如您所见,iframe 链接与 Javascript 中的链接存在差异(使用 http 而不是 https)。

在浏览器的控制台中,我看到此消息:

[blocked] The page at https://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open&assoc=49F1767931B31CD0C1258398007953C0&type=1 was not allowed to display insecure content from http://fangstjournalen.dtu.dk/fangst.nsf/iframe.xsp?open&assoc=49F1767931B31CD0C1258398007953C0&type=1&SessionID=9C21D5AF363C262E3CC37D0CDFBDFBCB35528ECC.

这显然是一个合理的理由。

但是什么是添加了“错误”的内容 - 我该如何解决这个问题?

我们的测试系统并非 100% 等同于我们的生产系统。生产中的 Nginx 在同一台服务器上(测试中的不同服务器),在测试中我们使用 LetsEncrypt for SSL - 但在生产中我们获得了证书。从托管中心。我们仅在生产环境中设置了 ssl_session_cache - 以及其他一些(我认为)细微的差异...

生产中 Nginx 服务器的配置如下所示(省略了其他服务器的一些细节):

server {
        listen 443;
        server_name fangstjournalen.dtu.dk;
 
        client_max_body_size 25m;
 
        ssl on;
        ssl_certificate /etc/Nginx/ssl/fangstjournalen.dtu.dk.pem;
        ssl_certificate_key /etc/Nginx/ssl/fangstjournalen.dtu.dk.key;
        ssl_session_cache shared:le_Nginx_SSL:1m;
        ssl_session_timeout 1440m;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "ECDHE-....";
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security max-age=15768000;

        # 2020.05.20/Jda - added Sync Gateway
        # Use a specific url pattern to identify sync requests - and remove that part before redirecting to the db server
        location /_sync {
              rewrite                 /_sync/(.*) /$1  break;
              proxy_pass              http://sync_gateway;
              :
              :
        }

        # 2019.11.04/Jda - Added keepalive_timeout,proxy_read_timeout: 600 --> 900
        # 2020.08.12/Jda - Added SameSite=none; Secure to cookies...
        location / {
                proxy_pass              http://fangstjournalen.dtu.dk:8088;
                proxy_redirect          off;
                proxy_buffering         off;
                proxy_http_version      1.1;
                keepalive_timeout       720s;
                proxy_read_timeout      900s;
                proxy_set_header        X-Forwarded-Port     8088;
                proxy_set_header        X-Forwarded-Host     $host;
                proxy_set_header        X-Forwarded-Server   $host;
                proxy_set_header        X-Real-IP            $remote_addr;
                proxy_set_header        Host                 $host;
                proxy_set_header        X-Forwarded-For      $proxy_add_x_forwarded_for;
                proxy_set_header        X-Forwarded-Proto    $scheme;
                proxy_set_header        $WSRA                $remote_addr;
                proxy_set_header        $WSRH                $remote_addr;
                proxy_set_header        $WSSN                $host;
                proxy_set_header        $WSIS                True;
                proxy_cookie_path       /                    "/; SameSite=none; Secure";
        }
}

非常感谢任何想法!

提前致谢;-)

/约翰

编辑:测试页面链接已被删除,因为该页面现在也已被删除:-)

解决方法

可以尝试使用sub_filter模块重写内容:

sub_filter_once on;
sub_filter_types text/html;
sub_filter '<script type="text/javascript">if(!navigator.cookieEnabled)window.location.href="http://' '<script type="text/javascript">if(!navigator.cookieEnabled)window.location.href="https://';
,

我遇到了同样的问题。使用反编译器,我在代码中找到了添加的地方。 您可以在 ExternalContextEx 上设置一个属性,以避免添加脚本标记。

我在我的应用程序的自定义 ViewHandler(重载 createView 方法)中执行此操作,但您也可以在 XPage 的 beforePageLoad 事件中执行此操作。

在我的代码中,如果 SessionID-cookie 未设置,我只会覆盖它,以防它做了我不知道的其他事情。到目前为止,没有任何问题。

HttpServletRequest httpServletRequest = (HttpServletRequest) facesContext.getExternalContext().getRequest();
if( !httpServletRequest.isRequestedSessionIdFromCookie() ) {
    ExternalContextEx externalContext = (ExternalContextEx) facesContext.getExternalContext();
    externalContext.setDonotEncodeUrl( false );
}