【问题标题】:Play 2.5 with Silhouette 4.0 - Credential Provider使用 Silhouette 4.0 玩 2.5 - 凭证提供者
【发布时间】:2016-12-21 07:49:48
【问题描述】:

我正在尝试编写一个带有 Play 2.5 的示例应用程序,使用 Silhouette 4.0 进行用户/密码身份验证。

源代码位于:https://github.com/pariksheet/dribble

我卡在 Environment 对象中设置 requestProvider

Environment[JWTEnv](
  identityService,
  authenticatorService,
  Seq(),
  eventBus
)

由于我无法找出解决方案,我将在我的所有控制器类中注入凭据提供程序。

    class MyController @Inject() (val messagesApi: MessagesApi,val silhouette: Silhouette[JWTEnv],
  authInfoRepository: AuthInfoRepository,
  credentialsProvider: CredentialsProvider)
    extends Controller {
          def authenticate = Action.async(BodyParsers.parse.json) { implicit request =>
        credentialsProvider.authenticate(Credentials(data.email, data.password)).flatMap { loginInfo => ..}    
         //   silhouette.env.requestProviders.foreach { x => println("====" + x.id) }  --- I am hoping to get credential provider from silhouette object

        ...
        ...
        }
    }

我的 Module.scala 如下 -

package module

import com.google.inject.AbstractModule
import com.google.inject.Provides
import com.mohiva.play.silhouette.api.Env
import com.mohiva.play.silhouette.api.Environment
import com.mohiva.play.silhouette.api.EventBus
import com.mohiva.play.silhouette.api.Silhouette
import com.mohiva.play.silhouette.api.SilhouetteProvider
import com.mohiva.play.silhouette.api.crypto.Base64AuthenticatorEncoder
import com.mohiva.play.silhouette.api.repositories.AuthInfoRepository
import com.mohiva.play.silhouette.api.services.AuthenticatorService
import com.mohiva.play.silhouette.api.services.AvatarService
import com.mohiva.play.silhouette.api.services.IdentityService
import com.mohiva.play.silhouette.api.util.CacheLayer
import com.mohiva.play.silhouette.api.util.Clock
import com.mohiva.play.silhouette.api.util.FingerprintGenerator
import com.mohiva.play.silhouette.api.util.HTTPLayer
import com.mohiva.play.silhouette.api.util.IDGenerator
import com.mohiva.play.silhouette.api.util.PasswordHasher
import com.mohiva.play.silhouette.api.util.PasswordHasherRegistry
import com.mohiva.play.silhouette.api.util.PasswordInfo
import com.mohiva.play.silhouette.api.util.PlayHTTPLayer
import com.mohiva.play.silhouette.impl.authenticators.JWTAuthenticator
import com.mohiva.play.silhouette.impl.authenticators.JWTAuthenticatorService
import com.mohiva.play.silhouette.impl.authenticators.JWTAuthenticatorSettings
import com.mohiva.play.silhouette.impl.providers.CredentialsProvider
import com.mohiva.play.silhouette.impl.services.GravatarService
import com.mohiva.play.silhouette.impl.util.DefaultFingerprintGenerator
import com.mohiva.play.silhouette.impl.util.PlayCacheLayer
import com.mohiva.play.silhouette.impl.util.SecureRandomIDGenerator
import com.mohiva.play.silhouette.password.BCryptPasswordHasher
import com.mohiva.play.silhouette.persistence.daos.DelegableAuthInfoDAO
import com.mohiva.play.silhouette.persistence.repositories.DelegableAuthInfoRepository

import daos.MongoUserDao
import daos.MongoUserTokenDao
import daos.PasswordInfoDao
import daos.UserDao
import daos.UserTokenDao
import models.User
import net.codingwell.scalaguice.ScalaModule
import play.api.Configuration
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.ws.WSClient
import services.UserService

trait JWTEnv extends Env {
  type I = User
  type A = JWTAuthenticator
}

class Module extends AbstractModule with ScalaModule {

  def configure() {
    bind[IdentityService[User]].to[UserService]
    bind[UserDao].to[MongoUserDao]
    bind[UserTokenDao].to[MongoUserTokenDao]
    bind[DelegableAuthInfoDAO[PasswordInfo]].to[PasswordInfoDao]
    bind[IDGenerator].toInstance(new SecureRandomIDGenerator())
    bind[PasswordHasher].toInstance(new BCryptPasswordHasher)
    bind[FingerprintGenerator].toInstance(new DefaultFingerprintGenerator(false))
    bind[EventBus].toInstance(EventBus())
    bind[Clock].toInstance(Clock())
    bind[CacheLayer].to[PlayCacheLayer]
    bind[Silhouette[JWTEnv]].to[SilhouetteProvider[JWTEnv]]
  }

  @Provides
  def provideHTTPLayer(client: WSClient): HTTPLayer = new PlayHTTPLayer(client)

  @Provides
  def provideEnvironment(
    identityService: IdentityService[User],
    authenticatorService: AuthenticatorService[JWTAuthenticator],
    eventBus: EventBus): Environment[JWTEnv] = {

    Environment[JWTEnv](
      identityService,
      authenticatorService,
      Seq(),
      eventBus
    )
  }

  @Provides
  def provideAuthenticatorService(
    fingerprintGenerator: FingerprintGenerator,
    idGenerator: IDGenerator,
    configuration: Configuration,
    clock: Clock): AuthenticatorService[JWTAuthenticator] = {
    val settings = JWTAuthenticatorSettings(
      sharedSecret = configuration.getString("application.secret").getOrElse("PARI"))


    new JWTAuthenticatorService(
      settings = settings,
      repository = None,
      authenticatorEncoder = new Base64AuthenticatorEncoder,
      idGenerator = idGenerator,
      clock = Clock())
  }

  @Provides
  def provideAuthInfoRepository(
    passwordInfoDAO: DelegableAuthInfoDAO[PasswordInfo]): AuthInfoRepository = {

    new DelegableAuthInfoRepository(passwordInfoDAO)
  }

  @Provides
  def providePasswordHasherRegistry(passwordHasher: PasswordHasher): PasswordHasherRegistry = {
    new PasswordHasherRegistry(passwordHasher)
  }

  @Provides
  def provideCredentialsProvider(
    authInfoRepository: AuthInfoRepository,
    passwordHasherRegistry: PasswordHasherRegistry): CredentialsProvider = {

    new CredentialsProvider(authInfoRepository, passwordHasherRegistry)
  }


  @Provides
  def provideAvatarService(httpLayer: HTTPLayer): AvatarService = new GravatarService(httpLayer)

}

你能帮帮我吗?

谢谢 帕里

【问题讨论】:

    标签: scala playframework silhouette


    【解决方案1】:

    请求提供者在您的 Module.scala 中设置,但它们设置为空序列:

    @Provides
    def provideEnvironment(
      identityService: IdentityService[User],
      authenticatorService: AuthenticatorService[JWTAuthenticator],
      eventBus: EventBus): Environment[JWTEnv] = {
    
      Environment[JWTEnv](
        identityService,
        authenticatorService,
        Seq(),                 // Here the request providers are set
        eventBus
      )
    }
    

    Ps:请记住,foreach 将始终“不返回”,因为它的类型是 unit

    【讨论】:

    • 谢谢莫里茨。我后来想通了。我已经在控制器中显式地注入了 val credentialsProvider: CredentialsProvider 。我现在可以使用凭据提供程序。不确定如何在环境中设置。什么是代码而不是 Seq()。任何想法。谢谢
    • @Moritz - 请您帮我做一些类似的事情,但用于编译时注入。 SO 问题是在stackoverflow.com/questions/49586114/… 创建的
    【解决方案2】:

    你在这里混合了两种不同的东西。凭证提供者不是请求提供者。请求提供者是一种特殊类型的提供者,可以直接挂接到请求中。详细说明可以在documentation 中找到。 Silhouette 提供了一个Basic Authentication provider,它是一个请求提供者的实现。

    凭据提供程序应直接注入到您的控制器中,如在seed template 中实现的那样。

    【讨论】:

    • 感谢您的信息。我想,我需要更彻底地阅读请求提供者。
    猜你喜欢
    • 2019-01-15
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 2016-04-26
    • 2020-06-28
    • 2018-05-07
    相关资源
    最近更新 更多