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""""))
}
}