質問

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