Play Framework REST with basic authentication and SSL

A very easy way is to use Action Composition. For a sample, take a look at this Gist provided by Guillaume Bort: https://gist.github.com/guillaumebort/2328236. If you want to use it in an async action, you can write something like:

def BasicSecured[A](username: String, password: String)(action: Action[A]): Action[A] = Action.async(action.parser) { request =>
  request.headers.get("Authorization").flatMap { authorization =>
    authorization.split(" ").drop(1).headOption.filter { encoded =>
      new String(org.apache.commons.codec.binary.Base64.decodeBase64(encoded.getBytes)).split(":").toList match {
        case u :: p :: Nil if u == username && password == p => true
        case _ => false
      }
    }
  }.map(_ => action(request)).getOrElse {
    Future.successful(Unauthorized.withHeaders("WWW-Authenticate" -> """Basic realm="Secured Area""""))
  }
}

SSL does not have anything to do with basic authentication. You can use HTTPS for API either directly or through a front-end HTTP server like ngnix. There are pretty good details in Play documentation on this subject.


basically, I have taken the answer from @centr and tried to make it a little more readable. See if you prefer this version of the same code. Tested thoroughly, works as expected.

def BasicSecured[A](username: String, password: String)(action: Action[A]): Action[A] = Action.async(action.parser) { request =>
    val submittedCredentials: Option[List[String]] = for {
      authHeader <- request.headers.get("Authorization")
      parts <- authHeader.split(' ').drop(1).headOption
    } yield new String(decodeBase64(parts.getBytes)).split(':').toList

    submittedCredentials.collect {
      case u :: p :: Nil if u == username && p == password => action(request)
    }.getOrElse {
      Future.successful(Unauthorized.withHeaders("WWW-Authenticate" -> """Basic realm="Secured Area""""))
    }
  }