Skip to content

Instantly share code, notes, and snippets.

@ricsirigu
Last active July 21, 2017 08:25
Show Gist options
  • Save ricsirigu/5fb7a57f8af53f93b76d344a5422bf3f to your computer and use it in GitHub Desktop.
Save ricsirigu/5fb7a57f8af53f93b76d344a5422bf3f to your computer and use it in GitHub Desktop.
JWT Authentication with Scala and Lift web framework
object jwtClaims extends TransientRequestVar[Option[String]](Empty)
case class JWTAuthentication(realmName: String)(func: PartialFunction[(String, Req), Boolean]) extends HttpAuthentication {
//Take the JWT from the Authorization header
def credentials(r: Req): Box[String] = {
header(r).flatMap{ token =>
if (Jwt.isValid(sanitizeHeader(token), secret, Seq(JwtAlgorithm.HS256))) {
Jwt.decode(sanitizeHeader(token), secret, Seq(JwtAlgorithm.HS256)) match {
case Success(payload) => Full(payload)
case Failure(_) => Empty
}
} else {
Empty
}
}
}
//If the credentials functions returns a Full box, func gets executed
override def verified_? : PartialFunction[Req, Boolean] = {
case (req) =>
credentials(req) match {
case Full(payload) if func.isDefinedAt(payload, req) =>
jwtClaims.set(Option(payload))
func(payload, req)
case _ => false
}
}
override def realm: String = realmName
}
object SecuredApi extends RestHelper{
def init() = {
def protectedRoutes: LiftRules.HttpAuthProtectedResourcePF = {
//Empty means that this resource is protected by authentication but no authorization is performed
case "api" :: "secured" :: "treasure" :: Nil JsonGet _ => Empty
}
LiftRules.httpAuthProtectedResource.append(protectedRoutes)
LiftRules.authentication = JWTAuthentication("api"){
case(payload, _) =>
true
}
LiftRules.statelessDispatch.append(SecuredApi)
}
serve("api" / "secured" prefix {
case "treasure" :: Nil JsonGet _ =>
//Here you can access jwtClaims TransientRequestVar
JString("My Treasure")
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment