scalaplayframework-2.0playframework-2.2

Restrict access to specific IP in Play Framework (Scala)


How can I restrict access to list of IP in Play Framework using Scala?

I'm using Play Framework 2.2.4

I found solution for Java: http://feadro.com/simple-ip-access-list-for-play-2-1-with-java/

How should I do it in Scala?


Solution

  • Stick the IPs you want to restrict to in the application.conf.

    myapp.ipwhitelist = ["192.168.1.1", ...]
    

    Then make a global filter which is applied to every incoming request, something like:

    import scala.collection.JavaConverters._
    import play.api.libs.concurrent.Execution.Implicits._
    import play.api.libs.iteratee.Iteratee
    import play.api.Play.current
    import play.api.mvc._
    
    object IPFilter extends EssentialFilter {
      def apply(nextFilter: EssentialAction) = new EssentialAction {
        def apply(requestHeader: RequestHeader) = {
          // read the IPs as a Scala Seq (converting from the Java list)
          val ips: Seq[String] = current.configuration.getStringList("myapp.ipwhitelist")
                .map(_.asScala).getOrElse(Seq.empty)
    
          // Check we've got an allowed IP, otherwise ignore the
          // request body and immediately return a forbidden.
          if (ips.contains(requestHeader.remoteAddress)) nextFilter(requestHeader)
          else Iteratee.ignore[Array[Byte]]
            .map(_ => Results.Forbidden(s"Bad IP! ${requestHeader.remoteAddress}"))
        }
      }
    }
    

    Then enable that in your application Global object:

    object Global extends WithFilters(IPFilter) with GlobalSettings
    

    If you want more flexibility you can use the same logic but with Action composition instead of a global filter.