如何将持久性添加到 Play Silhouette 密码哈希注册表?

How can I add persistence to Play Silhouette password hasher registry?

我正在查看 Play Silhouette 种子示例:

https://github.com/mohiva/play-silhouette-seed

很清楚如何向 UserDAOAuthTokenDAO 添加持久性,因为它们在内存中有实现 UserDAOImplAuthTokenDAOImpl,您可以覆盖它们并提供数据库实现,例如MongoUserDAOImplMongoAuthTokenDAOImpl.

然而,我对散列密码的存储位置感到困惑。示例中没有用于此的 DAO。

这是用户提交注册密码的地方:

https://github.com/mohiva/play-silhouette-seed/blob/master/app/controllers/SignUpController.scala#L80

val authInfo = passwordHasherRegistry.current.hash(data.password)

如何向 passwordHasherRegistry 添加持久性?

您可能不需要向 passwordHasherRegistry 添加持久性。 passwordHasherRegistry 是一个对象,其中包含用于对密码进行哈希处理的当前和历史哈希函数列表,以便您可以对其进行验证。

根据 Persistence docs page to persist hashed password information you should provide implementation of AuthInfoRepository trait. You may use DelegableAuthInfoRepository that delegates the work to instance(s) of DelegableAuthInfoDAO. See also Silhouette Persistence ReactiveMongo GitHub 存储库,它提供了一些基于 Mongo 的实现 MongoAuthInfoDAO

根据@SergGr的建议,我使用了https://github.com/mohiva/play-silhouette-persistence-reactivemongo模块来实现密码持久化。

该模块的文档显示了如何构建 DAO 实例:

val dao = new MongoAuthInfoDAO[PasswordInfo](reactiveMongoApi, config)

原例子绑定DAO如下:

bind[DelegableAuthInfoDAO[PasswordInfo]].toInstance(new InMemoryAuthInfoDAO[PasswordInfo])

很容易将其替换为

bind[DelegableAuthInfoDAO[PasswordInfo]].toInstance(new MongoAuthInfoDAO[PasswordInfo](reactiveMongoApi, config))

并尝试将所需的参数注入为

class SilhouetteModule @Inject() (reactiveMongoApi: ReactiveMongoApi, configuration: Configuration) extends AbstractModule with ScalaModule

这样就编译通过了,看来也有道理。但是,这将导致运行时错误,因为无法执行注入。看来我们在正确设置注入器之前尝试注入一些东西。

解决方案是完全删除此绑定并完全依赖

@Provides
def providePasswordInfoDAO(reactiveMongoApi: ReactiveMongoApi, config: Configuration): DelegableAuthInfoDAO[PasswordInfo] = {
  implicit lazy val format = Json.format[PasswordInfo]
  new MongoAuthInfoDAO[PasswordInfo](reactiveMongoApi, config)
}

这在文档中,但没有强调您应该使用这个而不是尝试自己创建一个实例。

需要注意的是,该实现创建了一个集合 auth.PasswordInfo,如果您尝试在 mongo shell 和 db.auth.PasswordInfo.find() 中检查它,您将得到一个错误。名称中的点是个问题,所以你必须使用 db["auth.PasswordInfo"].find().