I'm trying to craft a ScalaInterceptor that looks for an X-Forwarded-Proto header, so basically if its in production or behind a proxy then Play! auto redirects to SSL.

I've run into issues with getting this code to compile, and I'm also not sure whether this will work with the SecureSocial plugin. There are specific reasons why we aren't setting SSL=true in SecureSocial.conf that I won't go into here.

Here's what I have in my Global.scala

  def WithHttpsRedirect[A](action: Action[A]): Action[A] = {
    Action(action.parser) { request =>
      val result = action(request)
      request.headers.get("X-Forwarded-Proto").collect {
        case "https" =>
          result

        case "http" =>
          val url = "https://"+request.host+request.uri
          Redirect(url)

      } getOrElse {
        result
      }
    }
  }

  override def onRouteRequest(request: RequestHeader): Option[Handler] = {
    super.onRouteRequest(request).map { handler =>
      handler match {
        case a: Action[_] => WithHttpsRedirect(a)
        case _ => handler
      }
    }
  }

I'm getting a compiler error after the getOrElse:

[error]  found   : scala.concurrent.Future[play.api.mvc.SimpleResult]
[error]  required: play.api.mvc.Result
[error]         result
[error]         ^

Your help is greatly appreciated!

有帮助吗?

解决方案 2

Changed my method of attack, and instead implemented a filter instead of overriding onRouteRequest:

In Global.scala:

object Global extends WithFilters(HttpsFilter) with GlobalSettings

then HttpsFilter.scala:

import play.api.mvc.Results._
import play.api.mvc.{SimpleResult, RequestHeader, Filter}
import scala.concurrent._
import ExecutionContext.Implicits.global

object HttpsFilter extends Filter {

  def apply(next: (RequestHeader) => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = {
    request.headers.get("X-Forwarded-Proto").collect {
      case "https" =>
        next(request)

      case "http" =>
        val url = "https://"+request.host+request.uri
        Future{ Redirect(url) }

    } getOrElse {
      next(request)
    }
  }

}

其他提示

Replace:

Action(action.parser) { request =>

with:

Action.async(action.parser) { request =>

You made need to also replace:

Redirect(url)

with:

Future.successful(Redirect(url))
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top