Play 2.5 с Silhouette 4.0 - поставщик учетных данных
Я пытаюсь написать пример приложения для Play 2.5 с использованием Silhouette 4.0 для аутентификации пользователя и пароля.
Исходный код доступен по адресу: https://github.com/pariksheet/dribble
Я застрял при установке requestProvider в объекте Environment
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)
}
Не могли бы вы помочь мне здесь?
Спасибо пари
2 ответа
Вы смешиваете две разные вещи здесь. Поставщик учетных данных не является поставщиком запросов. Поставщик запроса - это специальный тип поставщика, который может быть напрямую подключен к запросу. Подробное описание можно найти в документации. Silhouette предоставляет провайдера базовой аутентификации, который является реализацией провайдера запросов.
Поставщик учетных данных должен напрямую вводиться в ваш контроллер, как это реализовано в начальном шаблоне.
Поставщики запросов установлены в вашем 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