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

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

我有如下的Akka指令结构

cors(){
   post {
      extractCredentials {
         credentials:Option[HttpCredentials] => {
            // I can successfully inspect the credentials here
         }
      }
   }
}

现在我尝试使用authenticateBasic,如

private def foo(credentials: Credentials):Option[FineAuthenticationResult] = {
      credentials match
        case Credentials.Provided(token) =>
          println(token)
          Some(ValidCredentials("foo"))
        case _ => Some(InvalidToken("foo"))
}

cors(){
   post {
       authenticateBasic(
                  realm = "Secure",
                  foo
                ) { authenticationResult =>
                  // Keep track of authorization results per channel and EVENT type
                  val additionalTags = Map(
                    "eventType" -> event.customEventType,
                    "channel" -> event.channel
                  )
                  authenticationResult match
                    case InvalidToken(message) =>
                      reject(CredentialsRejection(s"invalid token $message", additionalTags))
                    case InvalidCredentials(message) =>
                      reject(CredentialsRejection(s"invalid token $message", additionalTags))
                    case ValidCredentials(_) => complete(StatusCode.int2StatusCode(200))
                }
   }
}

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

Postman.post(uri = "/path/path",
        channel = Some("a_channel"),
        eventType = Some("a-request")) ~>
        addCredentials(getValidToken) ~>
        routes ~>
        check {
          status shouldBe StatusCodes.OK
        }

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

1l5u6lss

1l5u6lss1#

tldr

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

更多详情

authenticateBasic使用

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

在引擎盖下。authenticateBasicAsync使用

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

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

_ collect { case c: C => c }

将删除Credentials对象。

相关问题