akka http custom directive - async

25 views
Skip to first unread message

Muthu Jayakumar

unread,
Apr 24, 2018, 1:09:20 AM4/24/18
to Akka User List
Hello there,

I am trying to write a custom directive in akka http for something like authorize (with a bit of difference from what's available OOTB).

object AuthenticationUtils {
 
def generateUserRequest(implicit system: ActorSystem, executionContext: ExecutionContext): Directive1[UserRequest] = {
    optionalHeaderValueByName
("Authorization").flatMap {
     
case Some(tokenValue) if Token.isValidTokenHeader(tokenValue) =>
        val token
= Token.fromHeader(tokenValue).get
        val selection
= system.actorSelection("myauthenticator-actor-selection-here")
       
implicit val timeout: Timeout = Timeout(2 minutes) //may be implicit timeout?
        val future
= (selection ? RedisTokenActor.GenerateUserRequest(token)).mapTo[GenerateUserRequestResponse]
           
.map { r => r.optUserRequest}
       
/*onSuccess(future) { //this does not work.
          case Some(ur) => provide(ur)
          case _ => reject(AuthorizationFailedRejection)
        }*/

        val res
= Await.result(future, timeout.duration) //todo: make this async.
        res match
{
         
case Some(ur) => provide(ur)
         
case _ => reject(AuthorizationFailedRejection)
       
}

     
case _ =>  reject(AuthorizationFailedRejection)
   
}
 
}
}

My question is that, how do I async the execution of the `future` within a directive? When I use onSuccess, the return objects are not compatible.
Please advice on how do I resolve this. When I use it synchronously, the above code works as desired.

Thanks
Muthu

Muthu Jayakumar

unread,
Apr 24, 2018, 12:15:49 PM4/24/18
to Akka User List
Hello there,

I shall repost this at discuss.lightbend.com.

Thanks,
Muthu

Sergey Tolmachev

unread,
May 28, 2018, 12:11:02 PM5/28/18
to Akka User List
Also faced such a problem:

def withActiveAuth: Directive1[Session] = {
    optionalHeaderValueByName
("session") {
     
case Some(session) =>
       
val s = Session(session)
        onSuccess
(sessionRepository.validateSession(s)) { result =>
         
if (result) {
            provide
(s) <------ ERROR
         
} else {
            reject
(MalformedHeaderRejection("session", "This session is not active"))
         
}
       
}
     
case None =>
        reject
(MissingHeaderRejection("session"))
   
}
}

Error:(18, 22) type mismatch;
 found   : akka.http.scaladsl.server.Directive1[wtf.scala.coursetest.Session]
    (which expands to)  akka.http.scaladsl.server.Directive[(wtf.scala.coursetest.Session,)]
 required: akka.http.scaladsl.server.RequestContext => scala.concurrent.Future[akka.http.scaladsl.server.RouteResult]
              provide(s)



вторник, 24 апреля 2018 г., 19:15:49 UTC+3 пользователь Muthu Jayakumar написал:

Sergey Tolmachev

unread,
May 28, 2018, 12:20:21 PM5/28/18
to Akka User List
oops, I'm sorry, I understood it:

def withActiveSession: Directive1[Session] = {
    optionalHeaderValueByName
("session").flatMap {

     
case Some(session) =>
       
val s = Session(session)

        onSuccess
(sessionRepository.validateSession(s)).flatMap { result =>
         
if (result) {
            provide
(s)

         
} else {
            reject
(MalformedHeaderRejection("session", "This session is not active"))
         
}
       
}
     
case None =>
        reject
(MissingHeaderRejection("session"))
   
}
}



вторник, 24 апреля 2018 г., 8:09:20 UTC+3 пользователь Muthu Jayakumar написал:
Reply all
Reply to author
Forward
0 new messages