Skip to content
Snippets Groups Projects
Commit 81d0d66d authored by Felipe D'Abrantes's avatar Felipe D'Abrantes
Browse files

Create authentication middleware

parent 754d824c
No related branches found
No related tags found
1 merge request!14Add endpoints to manage Dailies
package models.actions
import models.actions.AuthenticationRequest
import play.api.mvc.{ActionBuilder, BodyParsers, Request, Result, AnyContent}
import scala.concurrent.Future
import javax.inject.Inject
import scala.concurrent.ExecutionContext
/**
* The authentication action builder that combines the request transformation and filtering.
*/
class AuthenticatedUserAction @Inject()(authenticationTransformer: AuthenticationTransformer, authenticationFilter: AuthenticationFilter)
(implicit val parser: BodyParsers.Default, val executionContext: ExecutionContext)
extends ActionBuilder[AuthenticationRequest, AnyContent] {
/**
* Invoke the main controller block, with the transformations and filtering middleware.
*
* @param request The incoming request.
* @param block The block of code to invoke.
* @return A future of the result.
*/
override def invokeBlock[A](request: Request[A], block: AuthenticationRequest[A] => Future[Result]): Future[Result] = {
(authenticationTransformer andThen authenticationFilter).invokeBlock(request, block)
}
}
package models.actions
import models.actions.AuthenticationRequest
import play.api.mvc.{ActionFilter, Result, Results}
import scala.concurrent.{Future, ExecutionContext}
import javax.inject.Inject
/**
* The authentication action filter that verifies the request contains a user ID.
*/
class AuthenticationFilter @Inject() (implicit val executionContext: ExecutionContext) extends ActionFilter[AuthenticationRequest] {
/**
* Determines whether to process a request.
* Decides whether to immediately intercept the request or continue processing the request.
*
* @param request The incoming request.
* @return An optional Forbidden Result with which to abort the request.
*/
override def filter[A](request: AuthenticationRequest[A]): Future[Option[Result]] = Future.successful {
if (!request.userId.isDefined)
Some(Results.Forbidden("Invalid JWT Token"))
else
None
}
}
package models.actions
import com.typesafe.config.ConfigFactory
import play.api.mvc.{ActionTransformer, Request, WrappedRequest}
import scala.concurrent.{Future, ExecutionContext}
import scala.util.Try
import org.bson.types.ObjectId
import pdi.jwt.{JwtJson, JwtAlgorithm, JwtClaim}
import play.api.libs.json.Json
import javax.inject.Inject
class AuthenticationRequest[A](val userId: Option[ObjectId], request: Request[A]) extends WrappedRequest[A](request)
/**
* The authentication action transformer that transforms the incoming base request to a user request.
*/
class AuthenticationTransformer @Inject() (implicit val executionContext: ExecutionContext) extends ActionTransformer[Request, AuthenticationRequest] {
/**
* Transforms the existing request from a Request to UserRequest.
*
* @param request The incoming request.
* @return The new parameter to pass to the Action block.
*/
override def transform[A](request: Request[A]) = Future.successful {
println(request)
val userId: Option[ObjectId] = processJWT(request)
new AuthenticationRequest(userId, request)
}
/**
* Processes the JWT token by decoding and validating it.
*
* @param request The incoming request.
* @return The user ID specified in the JWT's payload.
*/
def processJWT[A](request: Request[A]): Option[ObjectId] = {
val privateKey = ConfigFactory.load().getString("jwt.privateKey")
try {
val authHeader = request.headers.get("Authorization").get
val token = authHeader.substring(7)
println(s"JWT Token Received: $token")
val payload: Try[JwtClaim] = JwtJson.decode(token, privateKey, Seq(JwtAlgorithm.HS256))
val content = payload.get.content
val jsonContent = Json.parse(content)
val userId = (jsonContent \ "userId").as[String]
Some(new ObjectId(userId))
}
catch {
case ex: Throwable => {
println(ex)
None
}
}
}
}
......@@ -20,3 +20,4 @@ libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "5.0.0
libraryDependencies += "org.mongodb.scala" %% "mongo-scala-driver" % "4.3.0"
libraryDependencies += "com.typesafe.play" %% "play-ws" % "2.8.10"
libraryDependencies += "com.typesafe.play" %% "play-ahc-ws-standalone" % "2.1.10"
libraryDependencies += "com.github.jwt-scala" %% "jwt-play-json" % "9.2.0"
......@@ -2,3 +2,6 @@
mongodb.uri="mongodb://localhost:27017/"
mongo.feedService.db = "feed-service"
mongo.dailies.collection = "dailies"
# JWT Authenticationn
jwt.privateKey = ""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment