Created
September 18, 2016 19:39
-
-
Save janjaali/ce2bbffd14c614a49232dbc6dec4ba32 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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