2

I'm trying to integrate Deadbolt2 into my play framework 2.4 application.

A have following piece of code in my controller

import be.objectify.deadbolt.scala.{ActionBuilders, AuthenticatedRequest, DeadboltActions}
import be.objectify.deadbolt.scala.cache.HandlerCache
import play.api.data.Form
import play.api.data.Forms._
import play.api.mvc.{AnyContent, _}
import modules.user.security.{Authenticator, HandlerKeys, MyDeadboltHandler}

class Login @Inject() (deadbolt: DeadboltActions, handlers: HandlerCache, actionBuilder: ActionBuilders) extends Controller {
    //...
    def login = deadbolt.SubjectNotPresent() {
      Action { implicit request =>
        Ok(login(loginForm))
      }
    }
}

And I got error missing parameter type. I'm following deadbolt examples, which helps me a lot, but I can't figure out how to pass implicit request into action.

My template begins like this:

@(loginForm: Form[LoginForm])(implicit flash: Flash)

Using Action directly without deadbolt.SubjectNotPresent() works well.

Peter Krejci
  • 3,182
  • 6
  • 31
  • 49
  • What about your imports? – manub Feb 25 '16 at 21:20
  • @manub question updated – Peter Krejci Feb 25 '16 at 21:32
  • Which version of deadbolt are you using? If it's 2.4.4 there's been a change to switch out the implicit request for an explicit authenticated request. See https://github.com/schaloner/deadbolt-auth0-scala for an example. I'll write up a proper answer when I'm not using a smartphone. – Steve Chaloner Feb 26 '16 at 15:35
  • @SteveChaloner yes, I'm using 2.4.4. Thanks, I would really appreciate your help! – Peter Krejci Feb 26 '16 at 20:07
  • @PeterKrejci I've updated the docs at https://github.com/schaloner/deadbolt-2-scala - the answer is based (read: copy/pasted) from there. If the answer isn't clear, can you let me know so I can also improve the docs? – Steve Chaloner Feb 29 '16 at 07:15

1 Answers1

2

One persistent question that keeps coming up is "how do I get the subject in an authorized action?". As of Deadbolt 2.5, the request passed into an action has been replaced with an AuthenticatedRequest which contains an Option[Subject]. As users of 2.4 also want this feature, it has been included in 2.4.4 as a breaking change.

The following examples use SubjectPresent as an example, but the same change applies to all authorization constraints.

When using action builders, in place of

def index = actionBuilder.SubjectPresentAction().defaultHandler() { implicit request
  Ok(accessOk()) 
}

we now have

def index = actionBuilder.SubjectPresentAction().defaultHandler() { authRequest =>
  Future {
    Ok(accessOk()) 
  }
}

When using action composition, in place of

def index = deadbolt.SubjectPresent() { implicit request
    Action {
        Ok(accessOk())
    }
}

we now have

def someFunctionA = deadbolt.SubjectPresent()() { authRequest =>
  Future {
    Ok("Content accessible")
  }
}

The getSubject() function of the DeadboltHandler trait now takes an AuthenticatedRequest instead of a Request.

override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] = 
  request.subject match {
    case Some(user) => Future {request.subject}
    case None => // get from database, identity platform, cache, whatever
  }

What this means for your app is

def login = deadbolt.SubjectNotPresent() {
  Action { implicit request =>
    Ok(login(loginForm))
  }
}

becomes

def login = deadbolt.SubjectNotPresent()() { authRequest =>
  Future {
    Ok(login(loginForm))
  }
}
Steve Chaloner
  • 8,162
  • 1
  • 22
  • 38
  • Thanks a lot, everything works fine now! I'll continue using your documentation and I'll give you a feedback when my project moves on a little bit. – Peter Krejci Mar 03 '16 at 19:05