Created
August 4, 2016 12:27
-
-
Save faisal00813/a9da0ada77df41c5f376ced7d2f52d11 to your computer and use it in GitHub Desktop.
Deadbolt handler with JWT in scala
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 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