【问题标题】:Play Framework HTTPS ProxyPlay 框架 HTTPS 代理
【发布时间】:2012-07-07 02:01:09
【问题描述】:

我有戏!需要使用 HTTP 和 HTTPS 的应用程序。该应用程序在代理服务器(使用 Apache)后面运行,该代理服务器将 Web 请求转发到播放应用程序。

代理将一个端口用于 HTTP 请求,而另一个端口用于 HTTPs 请求。请注意,代理上的端口与 Play 应用程序使用的端口相同(这是由于提供商的限制!)。

Play 应用程序使用“标准”端口 9000 用于 HTTP,9443 用于 HTTP。代理在 8080 端口接收 HTTP 请求并将其转发到 Play 的 9000 端口。代理在 8090 端口接收 HTTPs 请求并将它们转发到 Play 的 9443 端口。

我的问题是,当我使用 secure() 方法使页面出现在 Play 中时,Play 的逻辑会导致应用程序尝试使用 9443 作为 HTTPS 的端口。这会导致请求丢失,因为代理正在使用不同的端口。

当我想从 HTTP 切换到 HTTP 时,似乎也会发生同样的情况。我似乎无法让系统转到代理使用的端口。

不知何故,我需要让系统转到代理服务器已知的端口,而不会搞砸我的路由。有没有办法做到这一点?

提前感谢任何帮助/见解。

【问题讨论】:

  • 您是将应用程序部署到系统还是作为独立游戏运行?还是玩 1.X 还是 2.X
  • 其实我以为单机是运行Play的唯一方式。还有其他方法???无论如何:当前应用程序正在专用机器上运行 Play 1.2.4。我正在使用 Play 命令行,所以我猜它是独立的。我将在 Play v2 上运行未来的应用程序,他们将需要解决相同问题的方法,因此希望您提出的任何答案都可以在以后的 Play 版本以及 v1.2.4 中使用...
  • 好的,这似乎是一个配置问题。首先,您是否尝试过迁移到 2.X?这就是我正在使用的东西,并且从我可以看到 play 不向后兼容?
  • 我打算在未来的项目中使用 v2.0,但由于各种原因我不能在这里(主要是:我有很多用户,并且我最初在升级时遇到的问题使得它太冒险了现在)。你为什么不告诉我你为 2.0 做了什么。配置要求可能没有改变,如果他们改变了,我将需要你的解决方案用于未来的项目。

标签: https playframework


【解决方案1】:

Play 应该识别请求来自的端口,并使用该端口。可能您的 apache 配置设置不正确。

您是否在您的 apache 配置中添加了以下行?

ProxyPreserveHost on

您可能还需要XForwardedSupport=127.0.0.1,具体取决于您的服务器配置。

【讨论】:

  • 事实证明,你的代理中确实有那条线。
  • 事实证明,Play 似乎确实识别了请求进入的端口,但是当在 HTTP 和 HTTPS 之间切换时,它似乎不知道切换代理端口。例如:我有一个页面通过我的代理端口 8080(转发到 Play 的端口 9000)显示没有问题。此页面有一个使用 Play 符号的登录页面的链接:@@{Application.loginPage().secure()}。
  • 当我点击链接时,Play 正确地尝试处理 HTTPs 请求。问题是 Play 不知道将此请求发送到端口 8090(我的代理 HTTPs 端口转发到 Play 的 9443)。它尝试在 8080 处执行请求,但失败了。我必须在浏览器上手动切换端口才能到达登录页面,然后当我成功登录时,我必须手动切换回 8080 才能查看常规 HTTP 页面。是否有一些配置(无论是在代理中还是在 Play 中)可以消除这个问题?
【解决方案2】:

我已经找到了自己的“答案”,尽管它有些杂乱无章。

事实证明,根据我从文档中可以确定的内容,当 Play 应用程序位于代理后面时,确实没有办法告诉 Play 在端口之间切换。这是因为尽管 Play 确实识别出请求进入的端口,但它无法告诉它在安全和不安全端口之间移动时应该使用哪个 proxy 端口。例如,它知道 HTTP 请求来自代理端口 8080,并且它知道对其端口 9000 的后续请求将来自该代理端口。当有人尝试使用 https 访问其端口 9443 时,它不知道要切换到另一个代理端口。因此,如果您有一个类似的页面 http://toproxy:8080/links 具有一个或多个使用secure() 方法激活https 的链接,然后Play 会将链接解析为https://toproxy:8080——尽管代理服务器可能希望将端口8090 用于HTTPS 请求。因为代理端口 8080 被重定向到 Play 的端口 9000,所以将该端口用于 HTTPS 请求总是会失败。在 Play 2.0 和 Play 1.X 中都是如此。

我相信 Play 需要一些标准配置参数来告诉它将代理端口映射到其 HTTP 和 HTTPS 端口。这样,当它位于代理服务器后面时,开发人员可以使用 secure() 方法,Play 将能够将 URL 解析到正确的代理端口。此功能应在 1.X 和版本 2 中可用。

直到有人真正实现这一点(如果我有时间,我可能会这样做,但我致力于做的所有事情,人们不应该屏住呼吸),我的结论是简单地使用 redirect() 方法在HTTP 和 HTTPS 代理端口。 redirect() 方法显然允许我们输入完整的 URL,因此我只需调用打开请求的页面的完整 URL。

例如:在上述页面http://toproxy:8080/links 中,我可能有一个指向我想使用 HTTPS 保护的登录页面的链接。为此,我创建了两个操作:一个用于重定向到代理 HTTPS 端口(在此示例中,称为 gotoLogin()),另一个用于实际呈现登录页面(在此示例中,将其称为 loginPage() 并给它一个/loginpage 的路由)。

在 gotoLogin() 中,我以以下方式重定向到 loginPage:

redirect("https://toproxy:8090/loginpage");

这使得 Play 在代理端口 8090 上进入,该端口被重定向到 Play 的端口 9443。

当用户正确登录时,我的身份验证操作只需使用另一个 redirect() 调用:

redirect("http://toproxy:8080/destination_page");

这会导致 Play 为不安全的请求返回正确的代理端口。

这不是解决此问题的最佳方法。代理服务器有可能以某种方式配置为在 HTTP 和 HTTPS 端口之间进行正确切换,但是对于不是代理服务器配置专家的人(这描述了我!),调查这可能需要一些时间。当然,最好的解决方案是在 Play 中实现我之前描述的那种代理端口处理。

但是这个解决方案很有效,可以适应许多不同的情况。除非有人提出另一种更好的解决方案,否则我正在使用这个解决方案。

【讨论】:

    猜你喜欢
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-27
    • 2019-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多