DI error - migrating to v5 and using persistence data store


#1

I’d a working sample code using Silhouette v4 and Play 2.5. I started migrating to Silhouette v5 and Play 2.6 and have run into the following dependency injection error at runtime:

1) No implementation for com.mohiva.play.silhouette.api.services.AuthenticatorService<com.mohiva.play.silhouette.impl.authenticators.BearerTokenAuthenticator> was bound. 
while locating com.mohiva.play.silhouette.api.services.AuthenticatorService<com.mohiva.play.silhouette.impl.authenticators.BearerTokenAuthenticator> 
for the 2nd parameter of security.AuthenticationModule.provideEnvironment(AuthenticationModule.scala:79) 
at security.AuthenticationModule.provideEnvironment(AuthenticationModule.scala:79) (via modules: com.google.inject.util.Modules$OverrideModule -> security.AuthenticationModule)

And here’s the relevant code that the error is pointing to. Line 79 is Environment[AuthenticationEnv](.

def provideEnvironment(
		userService: UserService,
		authenticatorService: AuthenticatorService[BearerTokenAuthenticator],
		eventBus: EventBus): Environment[AuthenticationEnv] = {
	Environment[AuthenticationEnv](
	  userService,
	  authenticatorService,
	  Seq(),
	  eventBus
	)
}

I’m a bit stumped as to why this is occurring as I’ve double checked the following:

  1. Have the necessary bindings i.e. bind[...] in the configure() method in my module i.e. AuthenticationModule.
  2. Have the @Provides annotations for the methods in my module.
  3. Have the module enabled in Play’s application.conf file
  4. Compared my module code with that of play-silhouette-seed example (v5) and don’t see anything that I’m doing fundamentally different.

Any thoughts on what else I need to double check or other ideas on troubleshooting.


#2

Hi,

Could you please show your binding for the AuthenticatorService?

Best regards,
Christian


#3

Here’s the complete listing of all the bindings.

  def configure() {
    bind[AuthenticatorRepository[BearerTokenAuthenticator]].to[BearerTokenDAO]
    bind[Silhouette[AuthenticationEnv]].to[SilhouetteProvider[AuthenticationEnv]]
    bind[IdentityService[User]].to[UserService]
    bind[DelegableAuthInfoDAO[PasswordInfo]].to[UserPasswordDAO]
    bind[DelegableAuthInfoDAO[OAuth2Info]].to[UserOAuth2DAO]

    bind[IDGenerator].toInstance(new SecureRandomIDGenerator(64))
    bind[PasswordHasher].toInstance(new BCryptPasswordHasher())
    bind[FingerprintGenerator].toInstance(new DefaultFingerprintGenerator(false))
    bind[EventBus].toInstance(EventBus())
    bind[Clock].toInstance(Clock())
  }

I should also point out, that if I’d add the following binding to the above code,

bind[CacheLayer].to[PlayCacheLayer]

then I additionally get this error:

No implementation for play.api.cache.AsyncCacheApi was bound.
while locating play.api.cache.AsyncCacheApi
for the 1st parameter of com.mohiva.play.silhouette.impl.util.PlayCacheLayer.<init>(PlayCacheLayer.scala:32)
at security.AuthenticationModule.configure(AuthenticationModule.scala:47) (via modules: com.google.inject.util.Modules$OverrideModule -> security.AuthenticationModule)

Perhaps, rather than the bindings, something else is going wrong under the hood - incorrect configurations, binary incompatibilities?.


#4

Hi,

your bindings are not enough. You do not have a binding for a AuthenticatorService. This is a binding for a AuthenticatorSrervice.

To your cache binding issue. If you bind the CacheLayer to the PlayCacheLayer implementation, then you must provide a binding for the AsyncCacheApi because it’s a dependency of the PlayCacheLayer implementation. So have you pulled the Play cache as dependency of your project? If not, please see: https://www.playframework.com/documentation/2.6.x/ScalaCache#Importing-the-Cache-API

Best regards,
Christian


#5

Thank you Christian for the pointer. Apparently the provideAuthenticatorService method had implementation details for the CookieAuthenticator instead of BearerTokenAuthenticator - a copy / paste error on my part and for unknown reason, I completely missed double checking this section of code and assumed all is good.