如何强制Play框架2始终使用SSL?

Mik*_*rts 16 ssl scala heroku playframework-2.0

我有一个在Heroku上运行的Play Framework应用程序,使用Heroku的SSL端点.

我想通过SSL仅提供所有页面.

最好的方法是什么?

到目前为止,我最好的解决方案是onRouteRequest在我的GlobalSettings路由器中使用并将non-SSL请求路由到特殊的重定向处理程序:

override def onRouteRequest(request: RequestHeader): Option[Handler] = {
  if (Play.isProd && !request.headers.get("x-forwarded-proto").getOrElse("").contains("https")) {
    Some(controllers.Secure.redirect)
  } else {
    super.onRouteRequest(request)
  }
}
Run Code Online (Sandbox Code Playgroud)

package controllers

import play.api.mvc._

object Secure extends Controller {

  def redirect = Action { implicit request =>
    MovedPermanently("https://" + request.host + request.uri)
  }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法完全从内部做到这一点GlobalSettings?还是更好的东西?

Dim*_*try 12

这是使用过滤器的另一种方式.这也使用严格的传输安全性来确保将来的请求转到https.

object HTTPSRedirectFilter extends Filter with Logging {

    def apply(nextFilter: (RequestHeader) => Future[SimpleResult])(requestHeader: RequestHeader): Future[SimpleResult] = {
        //play uses lower case headers.
        requestHeader.headers.get("x-forwarded-proto") match {
            case Some(header) => {
                if ("https" == header) {
                    nextFilter(requestHeader).map { result =>
                        result.withHeaders(("Strict-Transport-Security", "max-age=31536000"))
                    }
                } else {
                    Future.successful(Results.Redirect("https://" + requestHeader.host + requestHeader.uri, 301))
                }
            }
            case None => nextFilter(requestHeader)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


joh*_*ren 4

我们已经做了与您非常相似的操作,但使用了一个生成 MovedPermanently 而不是控制器方法的播放过滤器。

我认为 Heroku 没有更好的方法,或者至少我们找不到任何功能来禁用未加密的 HTTP。

  • 只需返回一个 Result(或 2.2 中的 Future[SimpleResult]),而不是调用下一个操作/基本操作 (2认同)