问题
I am trying to create the Environment
in Silhouette
but am unable to. I have defined the Identity
and Authenticator
as follows
trait SessionEnv extends Env {
type I = User
type A = SessionAuthenticator
}
Next, I suppose I have to create the Environment
. For that I have written the following code but am stick as I do not understand how to pass the different parameters expected by Environment
's apply
method
Environment companion object's apply method has signature
def apply[E <: Env](
identityServiceImpl: IdentityService[E#I],
authenticatorServiceImpl: AuthenticatorService[E#A],
requestProvidersImpl: Seq[RequestProvider],
eventBusImpl: EventBus
I know that I have to provide the implemention of IdentityService
. I have done so as follows
class UserService @Inject()(userDao:UsersRepository) extends IdentityService[User] {...}
User is defined as follows
case class UserProfile(
loginInfo:LoginInfo,
confirmed: Boolean,
email:Option[String],
firstName: Option[String],
lastName: Option[String],
passwordInfo:Option[PasswordInfo]
//oauth1Info: Option[OAuth1Info],
//avatarUrl: Option[String]) {
)
//representation of a user. A user has an Id and a profile
case class User (id:UUID, profile:UserProfile)
But what do I pass for other values required by apply - authenticatorServiceImpl: AuthenticatorService[E#A], requestProvidersImpl: Seq[RequestProvider], eventBusImpl: EventBus
val sessionEnv = com.mohiva.play.silhouette.api.Environment[SessionEnv](new UserService(userRepository),????)
Also, I suppose I don't have to use Guice
as I am using compile time injection. Is that correct?
UPDATE
I changed from SessionAuthenticatorService
to CookieAuthenticatorService
to try some code available online.
It seems my understanding that Silhouette
provides some default implementations isn't exactly correct. I thought that I could simply use the SessionAuthenticatorService
companion object defined in https://github.com/mohiva/play-silhouette/blob/master/silhouette/app/com/mohiva/play/silhouette/impl/authenticators/SessionAuthenticator.scala
but that is not the case. Looking at some code created in ScalaModule
, it seems that I'll have to create the required object myself but I'll need to do it in my AppLoader class (for compile time DI) instead of ScalaModule (for runtime DI). However, I still have not solved the problem. I do not know how to create the signer
required by CookieAuthenticatorService
val config = configuration.underlying.asInstanceOf[CookieAuthenticatorSettings]("silhouette.authenticator")
val fingerprintGenerator = new DefaultFingerprintGenerator(false)
val idGenerator = new SecureRandomIDGenerator()
val clock:Clock = Clock()
val authenticatorService: AuthenticatorService[CookieAuthenticator] = new CookieAuthenticatorService(config,None,,,fingerprintGenerator, idGenerator,clock) //STILL NEED TO FIND OUT HOW TO CREATE Signer AND CookieHeaderEncoding required by CookieAuthenticator service
val cookieEnv = com.mohiva.play.silhouette.api.Environment[CookieEnv](userIdentityService ,authenticatorService,Seq(),EventBus())
回答1:
Here is the implementation for cookie authenticator
import com.mohiva.play.silhouette.api.actions._
import com.mohiva.play.silhouette.api.{EventBus, SilhouetteProvider}
import com.mohiva.play.silhouette.api.crypto.CrypterAuthenticatorEncoder
import com.mohiva.play.silhouette.api.util.Clock
import com.mohiva.play.silhouette.crypto.{JcaCrypter, JcaCrypterSettings, JcaSigner, JcaSignerSettings}
import com.mohiva.play.silhouette.impl.authenticators.{CookieAuthenticatorService, CookieAuthenticatorSettings}
import com.mohiva.play.silhouette.impl.util.{DefaultFingerprintGenerator, SecureRandomIDGenerator}
import components._
import play.api.mvc.DefaultCookieHeaderEncoding
import controllers._
import play.api._
import services.db.cassandra.UserService
import play.filters.csrf._
import services.AtomicCounter
import play.api.ApplicationLoader.Context
import play.filters.HttpFiltersComponents
import router.Routes
class AppLoader extends ApplicationLoader {
override def load(context: ApplicationLoader.Context): Application = {
LoggerConfigurator(context.environment.classLoader).foreach {
_.configure(context.environment, context.initialConfiguration, Map.empty)
}
new AppComponents(context).application
}
}
class AppComponents (context: Context) extends BuiltInComponentsFromContext(context)
with CassandraRepositoryComponents
with HttpFiltersComponents
with AssetsComponents
with CSRFComponents
/*with SilhouetteComponents*/{ //TODOM - Would prefer SilhouetteComponent but creating an Environment requires IdentityService. UserService is an IdentifyService but it requires userRepository which is created here. Need to resolve this cross dependence
val userIdentityService = new UserService(userRepository) //responsible for retrieving user information (eg email id) from a database
val config = CookieAuthenticatorSettings()
val fingerprintGenerator = new DefaultFingerprintGenerator(false)
val idGenerator = new SecureRandomIDGenerator()
val clock:Clock = Clock()
val signer= new JcaSigner(new JcaSignerSettings("someSigner"))
val crypter = new JcaCrypter(new JcaCrypterSettings("someCrypter"))
val authenticatorEncoder = new CrypterAuthenticatorEncoder(crypter)
val cookieHeaderEncoding= new DefaultCookieHeaderEncoding()
val authenticatorService = new CookieAuthenticatorService(config, None, signer, cookieHeaderEncoding, authenticatorEncoder, fingerprintGenerator, idGenerator, clock)
val cookieEnv = com.mohiva.play.silhouette.api.Environment[CookieEnv](userIdentityService ,authenticatorService,Seq(),EventBus())
val defaultParser = new mvc.BodyParsers.Default()
val securedAction = new DefaultSecuredAction(new DefaultSecuredRequestHandler(new DefaultSecuredErrorHandler(messagesApi)), defaultParser )
val unsecuredAction = new DefaultUnsecuredAction(new DefaultUnsecuredRequestHandler(new DefaultUnsecuredErrorHandler(messagesApi)),defaultParser)
val userAware = new DefaultUserAwareAction(new DefaultUserAwareRequestHandler(),defaultParser)
val silhouette = new SilhouetteProvider[CookieEnv](cookieEnv,securedAction,unsecuredAction,userAware)
lazy val userRepositoryController = new UserController(userRepository, controllerComponents)
lazy val homeController = new HomeController(controllerComponents, csrfAddToken,csrfCheck,silhouette) //using Silhouette in only one controller for the moment
lazy val countController = new CountController(controllerComponents,new AtomicCounter())
lazy val asyncController = new AsyncController(controllerComponents, actorSystem)
lazy val userWSRoutes = new WSRouters.User.UserRouter(userRepositoryController) //TODOM - whatam i doing here?
lazy val router = new Routes(httpErrorHandler, homeController,userWSRoutes, countController,asyncController, assets)
}
来源:https://stackoverflow.com/questions/49586114/unable-to-create-environment-in-silhouette