我找到了我自己的“答案”,尽管它有点杂乱无章。
事实证明,根据我从文档中可以确定的内容,当 Play 应用程序位于代理后面时,确实没有办法告诉 Play 在端口之间切换。这是因为尽管 Play 确实识别出请求进入的端口,但它无法告诉在安全和不安全端口之间移动时应该使用哪个代理端口。例如,它知道 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:
重定向(“https://toproxy:8090/loginpage”);
这使得 Play 在代理端口 8090 上进入,该端口被重定向到 Play 的端口 9443。
当用户正确登录时,我的身份验证操作只需使用另一个 redirect() 调用:
重定向(“http://toproxy:8080/destination_page”);
这会导致 Play 为不安全的请求返回到正确的代理端口。
这不是这个问题的最佳解决方案。代理服务器有可能以某种方式配置为在 HTTP 和 HTTPS 端口之间进行正确切换,但是对于不是代理服务器配置专家的人(这描述了我!),调查这可能需要一些时间。当然,最好的解决方案是在 Play 中实现我之前描述的那种代理端口处理。
But this solution works and can be adapted to many different situations. Unless someone comes up with another better solution, this solution is the one I am using.