Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
  • Oct 10 13:41

    akkie on gh-pages

    updated site (compare)

  • Oct 10 06:35

    akkie on gh-pages

    updated site (compare)

  • Oct 10 06:23

    akkie on gh-pages

    updated site (compare)

  • Oct 10 06:21

    akkie on gh-pages

    updated site (compare)

  • Oct 10 06:08

    akkie on master

    Fixed Profile URL as v1 resourc… (compare)

  • Oct 10 06:08
    akkie closed #568
  • Oct 10 06:08
    akkie commented #568
  • Oct 10 02:26
    coveralls commented #568
  • Oct 10 02:26
    coveralls commented #568
  • Oct 10 02:26
    coveralls commented #568
  • Oct 10 02:26
    coveralls commented #568
  • Oct 10 02:26
    coveralls commented #568
  • Oct 10 02:12
    ViniciusMiana commented #568
  • Oct 10 02:09
    ViniciusMiana synchronize #568
  • Oct 09 13:56
    ViniciusMiana commented #568
  • Oct 09 04:51
    akkie commented #568
  • Oct 09 04:36
    ViniciusMiana opened #568
  • Sep 18 19:30
    akkie synchronize #551
  • Sep 09 15:53
    akkie commented #567
  • Sep 09 15:53

    akkie on gh-pages

    updated site (compare)

nafg
@nafg
@ahjohannessen I just had that. Maybe travis is having some hiccups. It doesn't normally happen to me.
setrar
@setrar

https://github.com/CollegeBoreal/play-silhouette-slick-mysql.g8

I am upgrading this g8 project to Play 2.7.3 supports Scala 2.13.0 but I am having classTag issue with the new DelegableAuthInfoDAO trait

play-silhouette-slick-mysql/app/daos/password/PasswordDAO.scala:16:7: class PasswordDAO needs to be abstract. Missing implementation for:
[error]   val classTag: scala.reflect.ClassTag[com.mohiva.play.silhouette.api.util.PasswordInfo] // inherited from trait DelegableAuthInfoDAO

https://github.com/CollegeBoreal/play-silhouette-slick-mysql.g8/blob/master/src/main/g8/app/daos/password/PasswordDAO.scala#L15

setrar
@setrar

A follow up to my question, I instantiate the Password DAO using the below Injection scheme in Silhouette 5.0.3

@Singleton
class PasswordDAO @Inject()(
    protected val dbConfigProvider: DatabaseConfigProvider,
    loginDao: LoginDAO)(implicit executionContext: ExecutionContext)
    extends DelegableAuthInfoDAO[PasswordInfo]
    with PasswordDTO
    with HasDatabaseConfigProvider[JdbcProfile] {
...

The Silhouette Module Binding follows the below snippet

class SilhouetteModule extends AbstractModule with ScalaModule {

  override def configure(): Unit = {
   ...
    // @provides provideAuthInfoRepository
    bind[DelegableAuthInfoDAO[PasswordInfo]].to[PasswordDAO]
}

Unfortunately, the new DelegableAuthInfoDAO trait doesn't seem to allow the same instantiation.

val silhouetteVersion = "6.0.1"

trait DelegableAuthInfoDAO[T <: AuthInfo] extends AuthInfoDAO[T] {

  /**
   * The class tag for the type parameter.
   */
  val classTag: ClassTag[T]
}

The previous DelegableAuthInfoDAO implementation used an abstract class.

val silhouetteVersion = "5.0.3"

abstract class DelegableAuthInfoDAO[T <: AuthInfo](implicit val classTag: ClassTag[T]) extends AuthInfoDAO[T]

What would be the new way to instantiate PasswordDAO?

I looked into the Change Log and couldn't find any new explanation regarding the new trait implementation.

Let me know if the chat is not the place to talk about this item, I will move it to the forum. Thanks, and please help

Christian Kaps
@akkie
@setrar Do you get a compile error? For the new implementation you must pass an implicit class tag. The abstract class has done this implicitly. Now you must pass it explicitly
setrar
@setrar

@akkie yes, I do get a compile Error

play-silhouette-slick-mysql/app/daos/password/PasswordDAO.scala:16:7: class PasswordDAO needs to be abstract. Missing implementation for:
[error]   val classTag: scala.reflect.ClassTag[com.mohiva.play.silhouette.api.util.PasswordInfo] // inherited from trait DelegableAuthInfoDAO

I then tried to mimic InMemoryAuthInfoDAO

  override def configure(): Unit = {
       ...
      bind[DelegableAuthInfoDAO[PasswordInfo]]
            .toInstance(new PasswordDAO[PasswordInfo])
  }

But it looks like I need to use .toInstance to create a new DelegableAuthInfoDAO

That doesn't sit well with the Injected dbConfig

class PasswordDAO[T <: AuthInfo] @Inject()(
    protected val dbConfigProvider: DatabaseConfigProvider,
    loginDao: LoginDAO)(implicit val classTag: ClassTag[T])
    extends DelegableAuthInfoDAO[T]
    with PasswordDTO
    with HasDatabaseConfigProvider[JdbcProfile] {
   ...

any workaround?

Christian Kaps
@akkie
You could use a Guice provider. The official seed template does use this already for some services. With a provider you can instantiate complex classes
Christian Kaps
@akkie
Could you post the code of your Dao?
setrar
@setrar

@akkie Thanks, I will look into the Provider solution from the seed.

A DAO's snippet below but you can find the entire gitter8 template here

https://github.com/CollegeBoreal/play-silhouette-slick-mysql.g8

@Singleton
class PasswordDAO @Inject()(
    protected val dbConfigProvider: DatabaseConfigProvider,
    loginDao: LoginDAO)(implicit executionContext: ExecutionContext)
    extends DelegableAuthInfoDAO[PasswordInfo]
    with PasswordDTO
    with HasDatabaseConfigProvider[JdbcProfile] {

  import profile.api._

  val passwords = lifted.TableQuery[PasswordTable]

  def getAll: Future[Seq[Password]] = db.run(passwords.result)

  override def find(loginInfo: LoginInfo): Future[Option[PasswordInfo]] =
    db.run {
      for {
        Some(fields) <- passwords
          .filter(_.password === loginInfo.providerKey)
          .result
          .map(_.headOption)
      } yield
        Some(
          PasswordInfo(hasher = fields.hasher,
                       password = fields.secret,
                       salt = fields.salt))
    }
...

To start a new project: (using play-2.7, scala 2.13 and latest Silhouette) not working

$ sbt new CollegeBoreal/play-silhouette-slick-mysql.g8

The previous SIlhouette 5.03 version

$ sbt new CollegeBoreal/play-silhouette-slick-mysql.g8 --branch play-2.6
Christian Kaps
@akkie
And this code:
class PasswordDAO[T <: AuthInfo] @Inject() (
  protected val dbConfigProvider: DatabaseConfigProvider,
  loginDao: LoginDAO
)(
  implicit 
  val classTag: ClassTag[T],
  executionContext: ExecutionContext
) extends DelegableAuthInfoDAO[T]
    with PasswordDTO
    with HasDatabaseConfigProvider[JdbcProfile] {
Doesn't work if you use:
bind[DelegableAuthInfoDAO[PasswordInfo]].to[PasswordDAO]
?
Normally, it should
Christian Kaps
@akkie
Normally T isn't really needed here:
class PasswordDAO @Inject() (
  protected val dbConfigProvider: DatabaseConfigProvider,
  loginDao: LoginDAO
)(
  implicit 
  val classTag: ClassTag[PasswordInfo],
  executionContext: ExecutionContext
) extends DelegableAuthInfoDAO[PasswordInfo]
    with PasswordDTO
    with HasDatabaseConfigProvider[JdbcProfile] {
setrar
@setrar
@akkie the second snippet (without using the type parameter [T]) does compile but it gives an Error. The same error is thrown when using the type parameter [T].
[error] application - 

! @7cm23k6mg - Internal server error, for (GET) [/] ->

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) No implementation for scala.reflect.ClassTag<com.mohiva.play.silhouette.api.util.PasswordInfo> was bound.
  while locating scala.reflect.ClassTag<com.mohiva.play.silhouette.api.util.PasswordInfo>
    for the 3rd parameter of daos.password.PasswordDAO.<init>(PasswordDAO.scala:18)
  at modules.SilhouetteModule.configure(SilhouetteModule.scala:78) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.SilhouetteModule)
Christian Kaps
@akkie
The class tag will be added by the compiler. So it seems that this isn't possible in this case due to the Guice magic. So you should use a Guice provider in this case
setrar
@setrar
@akkie great, I will. Thanks again
Shunsuke Wada
@letusfly85

Hi, now I’m implementing a play-silhouette OAuth2 and a Vue.js project.
I’m trying to redirect from the playframework project to the Vue.js project after successing authentication.

But, I cannot handle JWT of the play project on the Vue.js project.

Is there any good way to get X-Auth-Token on Vue.js project.
If I can, I want to use OAuth2 without redirect.

Christian Kaps
@akkie
@letusfly85 For me it's not really clear what you try to achieve. Could be a bit more specific?
Shunsuke Wada
@letusfly85
vue_silhouette.png

@akkie

Thank you, I want to like the above.

Christian Kaps
@akkie
@letusfly85 The second part of the OAuth2 flow, where the provider returns the access token (your JWT), is normally the only part Silhouette handles in this scenario. The first part of the OAuth2 flow is mostly handled client side in your Vue.js code. Am I right? So in this case, you start the flow from the client side. Your client redirects the user to the provider, where the authentication against the provider happens. The provider redirects the user to the Silhouette endpoint with the authorization code. Silhouette exchanges the authorization code against the access token. Now you have two possibilities. First you can initiate a Silhouette session (create an authenticator), so that the user is authenticated against your backend. In the second case, you don't need a Silhouette session bur rather the OAuth2 access token from the provider. In both cases your controller which acts as the OAuth2 endpoint in your Play app and which calls the OAuth2Provider.authenticate method, can send a redirect to your client. In this redirect you can include in both cases, the access token (your JWT) which you get as result from the authenticate method.
Altern Egro
@alternegro
Hello, is the 4.0 documentation worth reading or will it lead me down the wrong path?
Shunsuke Wada
@letusfly85
@akkie

@akkie
Thank you!

I tried the above way,
However, when the provider redirects to the silhouette endpoint,
silhouette module showed the following errors.

[/authenticate/google] ->

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[CryptoException: [Silhouette][JcaSigner] Invalid message format; Expected [VERSION]-[SIGNATURE]-[DATA]]]
Altern Egro
@alternegro
Are Silhouette versions meant to mirror the Play sub versions? ie Does Silhouette 4 > Play 2.4.x, Silhouette 6 -> Play 2.6?
nafg
@nafg
Seems like they're one off that. See https://www.silhouette.rocks/docs/releases
@alternegro
Altern Egro
@alternegro
@nafg Thanks!
Altern Egro
@alternegro
So judging from the 4.0 to 5.0 Migration guide, It looks like the changes introduced in Silhouette are really just to keep up with Play, rather than to change Silhouette itself. Does this mean that the 4.0 documentation and the Migration Guide have all the info required to get up and running, or I'm I better of working from the the seed?
Christian Kaps
@akkie
@letusfly85 Do you use the CsrfStateItemHandler? This will not work with your scenario!
@alternegro Do you migrate an existing app? If so, to which version of Play?
Shunsuke Wada
@letusfly85

@akkie

My silhouette.conf settings is below.
Should we change from secureCookie false to true (even if I use JWT..) ?

  # CSRF state item handler settings
  csrfStateItemHandler.cookieName="OAuth2State"
  csrfStateItemHandler.cookiePath="/"
  csrfStateItemHandler.secureCookie=false // Disabled for testing on localhost without SSL, otherwise cookie couldn't be set
  csrfStateItemHandler.httpOnlyCookie=true
  csrfStateItemHandler.expirationTime=5 minutes

This will not work with your scenario!

Oh.. I only want to get code from the provider and publish login event on silhouette middleware..

Christian Kaps
@akkie
You schould completely disable the state handler. This means, do not inject it into the OAuth2 provider. If Silhouette initiates the OAuth2 flow, then it sends a token in the OAuth2 state param. And in the second step it validates the token. In your case the first step is done by your client app. So Silhouette cannot validate the token, because it does not exists.
Shunsuke Wada
@letusfly85

If Silhouette initiates the OAuth2 flow, then it sends a token in the OAuth2 state param. And in the second step it validates the token.

Thank you.
So, should I change like the following way.

  # CSRF state item handler settings
  csrfStateItemHandler.cookieName="OAuth2State"
  csrfStateItemHandler.cookiePath="/"
  csrfStateItemHandler.secureCookie=false // Disabled for testing on localhost without SSL, otherwise cookie couldn't be set
  csrfStateItemHandler.httpOnlyCookie=false
  csrfStateItemHandler.expirationTime=5 minutes
Christian Kaps
@akkie
No, you can't disable it over the config. You must remove it from your Guice config
Shunsuke Wada
@letusfly85
I changed SilhouetteModule.scalalike below.
  @Provides
  def provideSocialStateHandler(
    @Named("social-state-signer") signer: Signer,
    csrfStateItemHandler: CsrfStateItemHandler): SocialStateHandler = {

    // new DefaultSocialStateHandler(Set(csrfStateItemHandler), signer)
    new DefaultSocialStateHandler(Set(), signer)
  }
Shunsuke Wada
@letusfly85
And I request from my vue.js code like below, and got an error.
    const code = this.$route.query.code
    const scope = this.$route.query.scope
    const targetUrl = `http://localhost:9000/authenticate/google`
    const params = {
      code: code,
      scope: scope
    }
    axios.post(targetUrl, params, (response) => {
      console.log(response)
    }, (error) => {
      console.error(error)
    })
com.mohiva.play.silhouette.impl.exceptions.UnexpectedResponseException: [Silhouette][google] Got unexpected response `{
  "error": "invalid_grant",
  "error_description": "Bad Request"
}`; status code: 400
Christian Kaps
@akkie
You shouldn't POST to the authentication endpoint. The redirect URL you define in the Google OAuth2 setting page, should be the Silhouette endpoint and not your JS app. Google will call the Silhouette endpoint with all the required params and then Silhouette will redirect to your JS app as mentioned in the previous post.
Shunsuke Wada
@letusfly85

Thank you, I succeeded sign in,

from vue.js https://accounts.google.com/o/oauth2/auth?response_type=code
and redirect to localhost:9000/authenticate/google from the provider.

and I can go to the Vue.js project like the following way, but how can I pass the token…? currently I do by queryString like ?token=…….

              result <- silhouette.env.authenticatorService.embed(
                token,
                Redirect(s"http://localhost:3000?token=${token}")
Christian Kaps
@akkie
Redirect is a Play Result implementation. You should have the same API to send cookies, headers, ...
Shunsuke Wada
@letusfly85
Thank you, I finally got by cookies (or query string), but withHeaders didn’t work.
Now, I can logged in by using oauth2, thank you. @akkie
Altern Egro
@alternegro
@akkie I'm starting a new 2.7 Play project with Macwire instead of Guice. Thanks
Christian Kaps
@akkie
Then you should start with seed and replace the Guice module with Macwire
gobandoGH
@gobandoGH
I am migrating a Silhouette based app from 5.0 to 6,1 and got the following error with PasswordInfoDAO implementation:
CreationException: Unable to create injector, see the following errors: 1) No implementation for scala.reflect.ClassTag<com.mohiva.play.silhouette.api.util.PasswordInfo> was bound. while locating scala.reflect.ClassTag<com.mohiva.play.silhouette.api.util.PasswordInfo> for the 2nd parameter of models.daos.PasswordInfoDAO.<init>(PasswordInfoDAO.scala:23) at modules.SilhouetteModule.configure(SilhouetteModule.scala:83) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.SilhouetteModule) 1 error
I understand the solution implies a Guice Provider method definition, but don´t know where and how to implement it.
Please help
Christian Kaps
@akkie
setrar
@setrar

Hi @akkie ,

I followed the migration guide but running into another issue.

I removed the bind and added the provider

override def configure(): Unit = {
   ...

    // set your own Environment [Type]
    bind[Silhouette[DefaultEnv]].to[SilhouetteProvider[DefaultEnv]]
    // @provides provideEnvironment [Implementation]
    bind[IdentityService[User]].to[UserDAO]
    // @provides provideAuthenticatorService
    bind[AuthenticatorRepository[JWTAuthenticator]].to[AuthenticatorDAO]
  }

  @Provides
  def providePasswordDAO(dbConfigProvider: DatabaseConfigProvider,
                         loginDao: LoginDAO): PasswordDAO =
    new PasswordDAO(dbConfigProvider, loginDao)

The project compiles but the AuthInfoRepository provider doesn't seem to find the DelegableAuthInfoDAO[PasswordInfo] provider

  /**
    * Provides the auth info repository.
    *
    * @param passwordInfoDAO The implementation of the delegable password auth info DAO.
    * @return The auth info repository instance.
    */
  @Provides
  def provideAuthInfoRepository(
      passwordInfoDAO: DelegableAuthInfoDAO[PasswordInfo]): AuthInfoRepository =
    new DelegableAuthInfoRepository(passwordInfoDAO)

It throws the below error

Unexpected exception
CreationException: Unable to create injector, see the following errors:

1) No implementation for com.mohiva.play.silhouette.persistence.daos.DelegableAuthInfoDAO<com.mohiva.play.silhouette.api.util.PasswordInfo> was bound.
  while locating com.mohiva.play.silhouette.persistence.daos.DelegableAuthInfoDAO<com.mohiva.play.silhouette.api.util.PasswordInfo>
    for the 1st parameter of modules.SilhouetteModule.provideAuthInfoRepository(SilhouetteModule.scala:182)
  at modules.SilhouetteModule.provideAuthInfoRepository(SilhouetteModule.scala:182) (via modules: com.google.inject.util.Modules$OverrideModule -> modules.SilhouetteModule)

I tried to force the connection using a @Named decorator

  @Provides
  @Named("password-repository")
  def providePasswordDAO(dbConfigProvider: DatabaseConfigProvider,
                         loginDao: LoginDAO): PasswordDAO =
    new PasswordDAO(dbConfigProvider, loginDao)

against the AuthInfoRepository provider but it's the same issue

 @Provides
  def provideAuthInfoRepository(
      @Named("password-repository")
      passwordInfoDAO: DelegableAuthInfoDAO[PasswordInfo]): AuthInfoRepository =
    new DelegableAuthInfoRepository(passwordInfoDAO)

please see the project at the below location, sorry, I am not familiar with Guice

https://github.com/CollegeBoreal/play-silhouette-slick-mysql

Thanks

Christian Kaps
@akkie
Could you try to define the binding as:
def providePasswordDAO(dbConfigProvider: DatabaseConfigProvider, loginDao: LoginDAO): DelegableAuthInfoDAO[PasswordInfo] =
    new PasswordDAO(dbConfigProvider, loginDao)
setrar
@setrar
@akkie Way better. Thanks a lot
Michael
@micmorris
Hey all, I'm trying to get the JWTAuthenticator working for my site in Play, I've started from the play-silhouette-seed and managed to get JWT sent back to the client in a Response Header called X-Auth-Token, however when I'm trying to visit other pages on the site, those pages don't send the token back to the server, so the user always gets redirected to log in again. I've found this problem in the archive and implemented it to save the token as a cookie, but still doesn't work: https://gitter.im/mohiva/play-silhouette/archives/2015/05/30
Christian Kaps
@akkie
The current version of Silhouette does only allow one authenticator per action. Do you provide an API in your web application? Or why do you need a JWT token? Could you please elaborate your application architecture a bit more?