Skip to content

Instantly share code, notes, and snippets.

@janjaali
Created September 18, 2016 19:39
Show Gist options
  • Save janjaali/ce2bbffd14c614a49232dbc6dec4ba32 to your computer and use it in GitHub Desktop.
Save janjaali/ce2bbffd14c614a49232dbc6dec4ba32 to your computer and use it in GitHub Desktop.
package de.example.filters
import javax.inject.Inject
import akka.stream.Materializer
import play.api.mvc._
import sun.misc.BASE64Decoder
import scala.concurrent.{ExecutionContext, Future}
class BasicAuthenticationFilter @Inject()(implicit val mat: Materializer, ec: ExecutionContext) extends Filter {
private object Credentials {
lazy val Username = "username"
lazy val Password = "supersecurepassword"
}
private object Constants {
lazy val AuthorizationHeaderName = "authorization"
lazy val BasicAuthenticationIdentifier = "Basic "
lazy val UsernamePasswordSplitter = ":"
lazy val Utf8Charset = "UTF-8"
}
private lazy val base64Decoder = new BASE64Decoder
private lazy val unauthorizedResult = Results.Unauthorized.withHeaders(("WWW-Authenticate", """Basic realm="MyRealm""""))
private def decodeBase64(authorizationPayload: String): String = {
val decodedByteArray = base64Decoder.decodeBuffer(authorizationPayload)
new String(decodedByteArray, Constants.Utf8Charset)
}
private def retrieveUsernamePassword(message: String): Option[(String, String)] = {
val usernamePassword = message.split(Constants.UsernamePasswordSplitter)
if (usernamePassword.length != 2) {
return None
}
Some(usernamePassword(0), usernamePassword(1))
}
override def apply(nextFilter: (RequestHeader) => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
requestHeader.headers.get(Constants.AuthorizationHeaderName) match {
case Some(authorizationPayload) =>
if (!authorizationPayload.startsWith(Constants.BasicAuthenticationIdentifier)) {
return Future.successful(unauthorizedResult)
}
val basicAuthenticationBody = authorizationPayload.replace(Constants.BasicAuthenticationIdentifier, "")
val decodedPayload = decodeBase64(basicAuthenticationBody)
retrieveUsernamePassword(decodedPayload) match {
case Some((username, password)) =>
if (username != Credentials.Username || password != Credentials.Password) {
return Future.successful(unauthorizedResult)
}
case None => return Future.successful(unauthorizedResult)
}
nextFilter(requestHeader)
case None => Future.successful(unauthorizedResult)
}
}
}
/**
* Register the BasicAuthenticationFilter for all incoming requests
* /
//import play.api.http.DefaultHttpFilters
//class Filters @Inject()(basicAuthFilter: BasicAuthenticationFilter) extends DefaultHttpFilters(basicAuthFilter)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment