scala – 如何实现多个Silhouette Authenticators?
发布时间:2020-12-16 18:31:58 所属栏目:安全 来源:网络整理
导读:我使用 play-silhouette-seed作为我的应用程序的模板.所以在我的项目中,我使用基于cookie的身份验证器(CookieAuthenticator).即使对于通过我的Twirl模板中嵌入的JavaScript的REST调用,这也非常好用.但是,现在我想在除浏览器之外的客户端中以编程方式进行REST
我使用
play-silhouette-seed作为我的应用程序的模板.所以在我的项目中,我使用基于cookie的身份验证器(CookieAuthenticator).即使对于通过我的Twirl模板中嵌入的JavaScript的REST调用,这也非常好用.但是,现在我想在除浏览器之外的客户端中以编程方式进行REST调用.因此,我必须在每个响应中检索Set-Cookie:authenticator = …元素并将其设置为我的请求的一部分.在我的Twirl模板中嵌入并在浏览器中呈现的JavaScript代码段中,这没有问题,因为我不需要处理它,但对于其他客户端(服务器等),这会导致头痛.
我想在我的CookieAuthenticator之外实现一个JWTAuthenticator.这甚至是支持,还是我必须完全切换到JWTAuthenticator?此外,我是否需要单独的操作,即使除了验证器之外一切都应该是相同的实现? 解决方法
是的,Silhouette允许您实现多个
authenticators.以下是如何实现
JWTAuthenticator 提供其JWT身份验证服务以及
CookieAuthenticator :
>正如道格拉斯刘已经在评论中指出的那样,你需要创建一个额外的environment类型.它应该将Identity与相应的Authenticator连接起来. 例如: trait CookieEnv extends Env { type I = Account type A = CookieAuthenticator } trait JWTEnv extends Env { type I = Account type A = JWTAuthenticator } >在Silhouette模块中实现JWT绑定.请查看play-silhouette-angular-seed以获取完整示例. 例如: class SilhouetteModule extends AbstractModule with ScalaModule { def configure() { bind[Silhouette[CookieEnv]].to[SilhouetteProvider[CookieEnv]] bind[Silhouette[JWTEnv]].to[SilhouetteProvider[JWTEnv]] // ... () } @Provides def provideCookieEnvironment( userService: AccountService,authenticatorService: AuthenticatorService[CookieAuthenticator],eventBus: EventBus): Environment[CookieEnv] = { Environment[CookieEnv]( userService,authenticatorService,Seq(),eventBus ) } @Provides def provideJWTEnvironment( userService: AccountService,authenticatorService: AuthenticatorService[JWTAuthenticator],eventBus: EventBus): Environment[JWTEnv] = { Environment[JWTEnv]( userService,eventBus ) } // ... @Provides def provideCookieAuthenticatorService( @Named("authenticator-cookie-signer") cookieSigner: CookieSigner,@Named("authenticator-crypter") crypter: Crypter,fingerprintGenerator: FingerprintGenerator,idGenerator: IDGenerator,configuration: Configuration,clock: Clock): AuthenticatorService[CookieAuthenticator] = { val config = configuration.underlying.as[CookieAuthenticatorSettings]("silhouette.authenticator") val encoder = new CrypterAuthenticatorEncoder(crypter) new CookieAuthenticatorService(config,None,cookieSigner,encoder,fingerprintGenerator,idGenerator,clock) } @Provides def provideJWTAuthenticatorService( @Named("authenticator-crypter") crypter: Crypter,clock: Clock): AuthenticatorService[JWTAuthenticator] = { val config = configuration.underlying.as[JWTAuthenticatorSettings]("silhouette.authenticator") val encoder = new CrypterAuthenticatorEncoder(crypter) new JWTAuthenticatorService(config,clock) } // ... } >将JWTAuthenticator configuration settings添加到silhouette.conf中: 例如: authenticator.fieldName = "X-Auth-Token" authenticator.requestParts = ["headers"] authenticator.issuerClaim = "Your fancy app" authenticator.authenticatorExpiry = 12 hours authenticator.sharedSecret = "!!!changeme!!!" >通过JWT创建单独的身份验证路由: 例如,在app.routes文件中,添加以下行: # JWT Authentication POST /api/jwt/authenticate controllers.auth.api.AuthController.authenticate >最后,在AuthController中,添加相应的authenticate方法. 示例代码(改编自 implicit val dataReads = ( (__ 'email).read[String] and (__ 'password).read[String] and (__ 'rememberMe).read[Boolean] ) (SignInForm.SignInData.apply _) def authenticate = Action.async(parse.json) { implicit request => request.body.validate[SignInForm.SignInData].map { signInData => credentialsProvider.authenticate(Credentials(signInData.email,signInData.password)).flatMap { loginInfo => accountService.retrieve(loginInfo).flatMap { case Some(user) => silhouette.env.authenticatorService.create(loginInfo).map { case authenticator if signInData.rememberMe => val c = configuration.underlying authenticator.copy( expirationDateTime = clock.now + c.as[FiniteDuration]("silhouette.authenticator.rememberMe.authenticatorExpiry"),idleTimeout = c.getAs[FiniteDuration]("silhouette.authenticator.rememberMe.authenticatorIdleTimeout") ) case authenticator => authenticator }.flatMap { authenticator => Logger.info(s"User ${user._id} successfully authenticated.") silhouette.env.eventBus.publish(LoginEvent(user,request)) silhouette.env.authenticatorService.init(authenticator).map { token => Ok(Json.obj("token" -> token)) } } case None => Future.failed(new IdentityNotFoundException("Couldn't find user.")) } }.recover { /* Login did not succeed,because user provided invalid credentials. */ case e: ProviderException => Logger.info(s"Host ${request.remoteAddress} tried to login with invalid credentials (email: ${signInData.email}).") Unauthorized(Json.obj("error" -> Messages("error.invalidCredentials"))) } }.recoverTotal { case e: JsError => Logger.info(s"Host ${request.remoteAddress} sent invalid auth payload. Error: $e.") Future.successful(Unauthorized(Json.obj("error" -> Messages("error.invalidPayload")))) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |