Briefly: my application uses the Play web framework version 2.5.1. I want to use the Deadbolt authorization system, and Slick to access the user-authorization information in my database. How can I do this? Deadbolt is made specifically for Play, and Play comes with Slick integrated out-of-the-box, so it ought to be possible if not very easy.
Based on "Integrating Deadbolt" from the Deadbolt documentation, I extended the DeadboltHandler
trait. Its abstract getSubject()
method seems like the place to do the database query (so says the documentation but without any example). That method receives as an argument an AuthenticatedRequest
and returns the Subject
, basically the user-id that was authenticated, along with roles and permissions (authorizations).
I am stuck, because while Play comes with Slick integration, the documentation describes only how to use it from within a Play controller. (Note I am wanting to do this using dependency injection since using global lookups is deprecated and error-prone)
I am successfully using Deadbolt in my controller to restrict access to certain resources, but the controller seems like the wrong place for Deadbolt to be doing database queries for authorization details (if it were, then the DeadboltHandler
would be purposeless). The controller constructor signature definition looks something like (note the controller accesses the default database that stores web content rather than the authorization database):
class Application @Inject()(
dbConfigProvider: DatabaseConfigProvider,
playConfig: play.api.Configuration,
deadbolt: DeadboltActions
) extends Controller {
That works. However, similarly annotating the DeadboltHandler
extension with @Inject
fails to provide Slick access to the database:
class AuthHandler @Inject()(@play.db.NamedDatabase("auth") dbConfigProvider: DatabaseConfigProvider)
extends DeadboltHandler {
the result being
not enough arguments for constructor AuthHandler: (dbConfigProvider: play.api.db.slick.DatabaseConfigProvider)services.AuthHandler.
Unspecified value parameter dbConfigProvider.
Obviously, Play does something special for controllers so that the @Inject
annotation works, something of which I lack understanding. I presume it is in the nature of constructing controllers using an injector rather than the new
keyword, but my search through the Play source code has failed to show me what exactly is happening. If I could find that, perhaps I could mimic that technique to construct a DeadboltHandler
.
I see that play comes with classes such as GuiceInjector and GuiceInjectorBuilder, which sound as if they might be part of the solution, but my experimentation has yet failed to show me how, and if there is any documentation on how to use them in the specific context of a DeadboldHandler
extension, I am missing it.
I found this previous question: Scala (Play 2.4.x) How to call a class with @inject() annotation, which seems very much on point. Unfortunately, despite a half-dozen follow-up comments from the original poster, it is yet unanswered. I feel if I had the answer to that question I would have the answer to this question, though my question is very specific: how to use Play and Deadbolt and Slick with each other (in Scala).
What baffles me most is that this seems like something that ought to be common enough that it would be either mentioned in the documentation or have been asked about already on SO. My failure to find any such references typically means I am doing something so uniquely wrong that nobody else has ever had occasion to talk about it. It certainly seems as if it ought to be simple enough that I am optimistically hoping that I am missing something very basic, and I look forward to some kind soul informing me of that knowledge.