Akka HTTP:凭据未传播到authenticateBasic方法

inb24sb2  于 2023-10-18  发布在  其他
关注(0)|答案(1)|浏览(215)

我有如下的Akka指令结构

  1. cors(){
  2. post {
  3. extractCredentials {
  4. credentials:Option[HttpCredentials] => {
  5. // I can successfully inspect the credentials here
  6. }
  7. }
  8. }
  9. }

现在我尝试使用authenticateBasic,如

  1. private def foo(credentials: Credentials):Option[FineAuthenticationResult] = {
  2. credentials match
  3. case Credentials.Provided(token) =>
  4. println(token)
  5. Some(ValidCredentials("foo"))
  6. case _ => Some(InvalidToken("foo"))
  7. }
  8. cors(){
  9. post {
  10. authenticateBasic(
  11. realm = "Secure",
  12. foo
  13. ) { authenticationResult =>
  14. // Keep track of authorization results per channel and EVENT type
  15. val additionalTags = Map(
  16. "eventType" -> event.customEventType,
  17. "channel" -> event.channel
  18. )
  19. authenticationResult match
  20. case InvalidToken(message) =>
  21. reject(CredentialsRejection(s"invalid token $message", additionalTags))
  22. case InvalidCredentials(message) =>
  23. reject(CredentialsRejection(s"invalid token $message", additionalTags))
  24. case ValidCredentials(_) => complete(StatusCode.int2StatusCode(200))
  25. }
  26. }
  27. }

foo验证码总是以“Missing credentials”(缺少凭据)的情况结束。我在测试

  1. Postman.post(uri = "/path/path",
  2. channel = Some("a_channel"),
  3. eventType = Some("a-request")) ~>
  4. addCredentials(getValidToken) ~>
  5. routes ~>
  6. check {
  7. status shouldBe StatusCodes.OK
  8. }

为什么使用authenticateBasic时我总是得到丢失的凭据,而使用extractCredentials时总是给我正确的凭据。

1l5u6lss

1l5u6lss1#

tldr

这个问题很简单,但我不得不通过authenticateBasic的内部来了解问题所在。我们不能将authenticateBasicOAuth2Token一起使用。我们只能使用authenticateOAuth2

更多详情

authenticateBasic使用

  1. def authenticateBasicAsync[T](realm: String, authenticator: AsyncAuthenticator[T]): AuthenticationDirective[T] =
  2. extractExecutionContext.flatMap { implicit ec =>
  3. authenticateOrRejectWithChallenge[BasicHttpCredentials, T] { cred =>
  4. authenticator(Credentials(cred)).fast.map {
  5. case Some(t) => AuthenticationResult.success(t)
  6. case None => AuthenticationResult.failWithChallenge(HttpChallenges.basic(realm))
  7. }
  8. }
  9. }

在引擎盖下。authenticateBasicAsync使用

  1. def authenticateOrRejectWithChallenge[C <: HttpCredentials: ClassTag, T](
  2. authenticator: Option[C] => Future[AuthenticationResult[T]]): AuthenticationDirective[T] =
  3. extractCredentialsAndAuthenticateOrRejectWithChallenge(extractCredentials.map(_ collect { case c: C => c }), authenticator)

这里我们可以看到C原则上是BasicHttpCredentials。但是对于addCredentials-在OAuth0的情况下-C将是OAuth0Token。因此,该collect

  1. _ collect { case c: C => c }

将删除Credentials对象。

展开查看全部

相关问题