JWT Authentication with Play Framework


In this blog, I will demonstrate how to implement JWT Authentication with Play Framework.

JSON Web Token (JWT) is a compact, self-contained which means securely transfer the information between two parties. It can be sent via Post request or inside the HTTP header. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret or a public/private key pair using RSA It consists three parts separated by the dot(.)  i.e Header, Payload and Signature. The header consists type of the token and hashing algorithm, the payload contains the claims and the claims in a JWT are encoded as a JSON object that is used as the payload or as the plaintext, the signature part is used to verify that the sender of the JWT.

Here, we are using JSON Web Token for authentication with Play Framework, This is a most common way of using JWT. Once the user is logged in, we need to include JWT with each request that allows the user to access the routes, service and resources which authenticate the token in order to permit the request.

Let’s start with the implementation of JWT Authentication using Play Framework:

1. First, we need to include JWT library in our project. There are several libraries for JWT, you can use any of them depending on your requirement, here I am using one of the library i.e.

"com.jason-goodwin" %% "authentikat-jwt" % "0.4.1"

2. Next, you need to create JWT utility class in which you need to add all these methods for creating, verifying and decode the JWT token and provide the secret key and algorithm such as HMAC, SHA256.

val JwtSecretKey = "secretKey"
val JwtSecretAlgo = "HS256"

def createToken(payload: String): String = {
  val header = JwtHeader(JwtSecretAlgo)
  val claimsSet = JwtClaimsSet(payload)

  JsonWebToken(header, claimsSet, JwtSecretKey)
}

def isValidToken(jwtToken: String): Boolean =
  JsonWebToken.validate(jwtToken, JwtSecretKey)

def decodePayload(jwtToken: String): Option[String] =
  jwtToken match {
    case JsonWebToken(header, claimsSet, signature) => Option(claimsSet.asJsonString)
    case _                                          => None
  }

3. To implement JWT authentication, we need to create reusable custom secured action by using ActionBulder that authenticates the each subsequent request and verifies the JWT in order to permit the request to access the corresponding service. ActionBulder is the special case of functions that take request as input and thus can build actions and provides several factory methods that help for creating action. To implement ActionBuilder, we need to implement invokeBlock method. So here I have created a custom JWTAuthentication by using ActionBuilder.

case class User(email: String, userId: String) 
case class UserRequest[A](user: User, request: Request[A]) extends WrappedRequest(request)

object JWTAuthentication extends ActionBuilder[UserRequest] {
  def invokeBlock[A](request: Request[A], block: (UserRequest[A]) => Future[Result]): Future[Result] = {
    implicit val req = request

    val jwtToken = request.headers.get("jw_token").getOrElse("")

    if (JwtUtility.isValidToken(jwtToken)) {
      JwtUtility.decodePayload(jwtToken).fold(
        Future.successful(Unauthorized("Invalid credential"))
      ) { payload =>
        val userInfo = Json.parse(payload).validate[User].get

        // Replace this block with data source
        if (userInfo.email == "test@example.com" && userInfo.userId == "userId123") {
          Future.successful(Ok("Authorization successful"))
        } else {
          Future.successful(Unauthorized("Invalid credential"))
        }
      }
    }
    else {
      Future.successful(Unauthorized("Invalid credential"))
    }
  }
}

4. Now we can use “JWTAuthentication” the same way we use Action.

def index = JWTAuthentication { implicit request =>
  Ok(views.html.index("Hello world"))
}

5.  You can test it through Postman(on which you can send the request and view response),  all we need to do is create a JWT and pass it to the Headers, corresponding to the field “jw_token”. You can create JSON web token by “createToken” method that I have shown you in step 2 by passing payload as a parameter which can be anything, here is the example: 

val payload = """{"email":"test@example.com","userId":"userId123"}"""

JWT looks like this:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAZXhhbXBsZS5jb20iLCJ1c2VySWQiOiJ1c2VySWQxMjMifQ.mjMQN8m_wH1NSE9GGexCW_GUh8uruNco18jgt7AWuO4

jwt.png

You can get the source code from here.

I hope this blog is helpful to you!

Thanks 

References:
 

KNOLDUS-advt-sticker

About teenaVashist

Teena is a Software Consultant at Knoldus Software LLP having 2 year experience working in Scala. She is very enthusiastic towards her work and good at working in team. She is very much keen to learn new technologies. She is familiar with programming language's such as Scala, Css, Javascript, HTML, Java. She likes reading novels and watching movies.
This entry was posted in JWT, Play 2.4.X, Play Framework, Scala and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s