Skip to content

Instantly share code, notes, and snippets.

@faisal00813
Created August 4, 2016 12:27
Show Gist options
  • Save faisal00813/a9da0ada77df41c5f376ced7d2f52d11 to your computer and use it in GitHub Desktop.
Save faisal00813/a9da0ada77df41c5f376ced7d2f52d11 to your computer and use it in GitHub Desktop.
Deadbolt handler with JWT in scala
package api_security
import java.util
import be.objectify.deadbolt.core.models.{Permission, Role, Subject}
import be.objectify.deadbolt.scala.cache.HandlerCache
import io.igl.jwt._
import play.api.inject.{Binding, Module}
import play.api.libs.json.{JsBoolean, JsString, JsValue}
import play.api.{Configuration, Environment, Logger}
import utilities.GlobalConstants._
import utilities.HelperFunctions
import scala.collection.JavaConversions._
//import play.api.mvc.Security.AuthenticatedRequest
/**
* Created by faisal on 28/3/16.
*/
import javax.inject.Singleton
import be.objectify.deadbolt.scala.{AuthenticatedRequest, DeadboltHandler, DynamicResourceHandler, HandlerKey}
import play.api.mvc.{Request, Result, Results}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
class MyDeadboltHandler extends DeadboltHandler {
var PureAccessToken = Some("")
override def beforeAuthCheck[A](request: Request[A]): Future[Option[Result]] = {
if (request.headers.get(AuthKeyword).isEmpty){
Future{Some(Results.Unauthorized("header does not have access token"))}
}else{
PureAccessToken = Some(request.headers.get(AuthKeyword).get.replace("Bearer",""))
PureAccessToken = Some(request.headers.get(AuthKeyword).get.replace("Bearer ",""))
Future{None}
}
}
override def getDynamicResourceHandler[A](request: Request[A]): Future[Option[DynamicResourceHandler]] = Future {None}
override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] =
request.subject match {
case Some(user) => Future.successful(request.subject)
case _ =>
try{
// val decodedAT = JWTAccessTokenRepo.decodeAccessToken(PureAccessToken.get)
PureAccessToken match {
case Some("") => Future.successful(None)
case Some(adt) => Future {
HelperFunctions.getUserFromCurrentRequest(request)
}
}
}catch{
case ex:Exception=>Future.successful(None)
}
}
//TODO call the userdetails from authserver by sending user id
// get from database, identity platform, cache, etc, if some
// identifier is present in the request, otherwise Future(None)
override def onAuthFailure[A](request: AuthenticatedRequest[A]): Future[Result] = {
Future{Results.Unauthorized("Unauthorized user")}
}
}
@Singleton
class MyHandlerCache extends HandlerCache {
val defaultHandler: DeadboltHandler = new MyDeadboltHandler()
override def apply(): DeadboltHandler = defaultHandler
override def apply(handlerKey: HandlerKey): DeadboltHandler = defaultHandler
}
class CustomDeadboltHook extends Module {
override def bindings(environment: Environment, configuration: Configuration): Seq[Binding[_]] = Seq(
bind[HandlerCache].to[MyHandlerCache]
)
}
object JWTAccessTokenRepo {
def decodeAccessToken(accessToken:String) = {
// Typ("JWT")
Iss("rideIT_AS")
try {
val uid = DecodedJwt.validateEncodedJwt(accessToken, "QnTU3OEI8xwMQ341}4ZwlR8$Elm_q(*&^KJHT", Algorithm.HS256, Set(), Set(Iat,Iss,Sub,Exp,email,roles,cEmail_verf))
Some(User(uid.get.getClaim[Sub].get.value,uid.get.getClaim[email].get.value
,uid.get.getClaim[roles].get.value,uid.get.getClaim[cEmail_verf].get.value))
} catch {
case e: Exception =>
Logger.error( message ="invalid access token ->" + e.getMessage)
"invalid access token"
}
}
}
case class User (val id:String,val email:String,val csv_roles:String,val cEmail_verified:Boolean) extends Subject {
override def getRoles: util.List[_ <: Role] = {
csv_roles.split(",").map((x:String) =>UserRole(x)).toList:List[UserRole]
}
override def getPermissions: util.List[_ <: Permission] = ???
override def getIdentifier: String = id
}
case class UserRole(name:String) extends Role {
override def getName: String = name
}
///definations for the custom claim types
case class email(value:String) extends ClaimValue{
override val field: ClaimField = email
override val jsValue: JsValue = JsString(value)
}
object email extends ClaimField {
// A function that attempts to construct our claim from a json value
override def attemptApply(value: JsValue): Option[ClaimValue] =
value.asOpt[String].map(apply)
// The field name
override val name: String = "email"
}
case class roles(value:String) extends ClaimValue{
override val field: ClaimField = roles
override val jsValue: JsValue = JsString(value)
}
object roles extends ClaimField {
// A function that attempts to construct our claim from a json value
override def attemptApply(value: JsValue): Option[ClaimValue] =
value.asOpt[String].map(apply)
// The field name
override val name: String = "roles"
}
case class cEmail_verf(value:Boolean) extends ClaimValue{
override val field: ClaimField = cEmail_verf
override val jsValue: JsValue = JsBoolean(value)
}
object cEmail_verf extends ClaimField {
// A function that attempts to construct our claim from a json value
override def attemptApply(value: JsValue): Option[ClaimValue] =
value.asOpt[Boolean].map(apply)
// The field name
override val name: String = "cEmail_verf"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment