使用 REST Http 进行 Akka 身份验证



我正在使用Akka Basic Authentication和scala测试Json HTTP Routes。但是这些路由无法根据需要工作。这是代码

首先,安全路由不适用于邮递员BasicAuth。我需要添加一封电子邮件"安全/test@test.com"来触发登录操作。其次,子路由篮子根本不工作。邮递员说未知路线。那么我怎样才能用Postman BasicAuth Http Header来做到这一点呢?我必须发送什么样的请求只是"安全或电子邮件和密码一起发送。 其次,我怎样才能使子路由篮子演员/添加工作。

~ Route.seal {
(pathPrefix("secured") & get) {
authenticateBasic(realm = "secure site", myUserPassAuthenticator) { email =>
path(Segment) { segment =>
var user = User.USER_LIST.find(_.id == segment)
if (user.isDefined)
complete(s"Hi '$email' you logged in")
else complete(s"login failed Please register at ${"users" / "register"}")
}
} ~ path("basketActor") {
(pathEnd & get) {
implicit val timeout = Timeout(3 seconds)
onSuccess((basketActor ? GetBasketProducts).mapTo[BasketList]) { res =>
complete(BasketContainer(products = res.products))
}
} ~ (path("add" / IntNumber) & post) { number =>
val product = Product.PRODUCT_LIST.find(_.id == number)
if (product.isDefined) {
product.foreach { product =>
basketActor ! AddProductToBasket(product)
//            complete(Basket.BASKET_LIST ::= product)
}
complete(product)
} else complete("Not found")
}
}
}
}
def myUserPassAuthenticator(credentials: Credentials): Option[String] =
credentials match {
case p@Credentials.Provided(id) if p.verify("secret") => Some(id)
case _ => None
}

所以我的预期结果应该是用户调用安全路由登录,然后他可以访问篮子演员路由。但是现在路线无法访问,安全路线也不起作用

以下是基本身份验证在 Akka HTTP 中的工作方式:

HTTP 请求中的Authorization标头用于基本身份验证,它包含使用base64编码编码的用户名和密码。authenticateBasic路由将从标头中提取此信息以创建Credentials对象,然后将其传递给myUserPassAuthenticator方法。此方法应检查用户名和密码是否匹配,如果成功,则应返回表示系统中该用户的对象,或在失败时返回None

authenticateBasic的第二个(柯里)参数是一个函数,它获取用户数据并返回一个Route。因此,在您的情况下,email参数将包含myUserPassAuthenticator返回的id值。此函数应返回包含需要身份验证的所有路径的路由。

重要的是要

意识到,没有使用基本身份验证"登录"的概念。只有正确或不正确的身份验证凭据。(如果要具有登录/注销语义,则需要迁移到基于令牌的身份验证机制)。


因此,要使路由正常工作,您需要将查找用户 ID 的逻辑移动到myUserPassAuthenticator中,并返回user对象作为结果。碰巧您可以只返回find的结果,因为这已经返回了一个Option[User]

您还需要确保所有经过身份验证的路由都在authenticateBasic路由内。目前,basketActoradd路由处于同一级别,因此未进行身份验证。


示例路由如下所示。我使用了concat而不是~,因为我认为它更清楚。

pathPrefix("secured") {
authenticateBasic(realm = "secure site", myUserPassAuthenticator) { user =>
concat(
(pathEnd | pathSingleSlash) {
get {
complete(s"User $user Authenticated OK")
}
},
path("basketActor") {
(pathEnd & get) {
complete(s"basketActor for $user")
}
},
path("add" / IntNumber) { number =>
post {
complete(s"User $user posted $number")
}
}
)
}
}

请注意,用户 ID(电子邮件地址)不在 URL 中,而是在Basic Authentication标头的请求中。

要使用 Postman 对此进行测试,您需要创建一个带有 URL.../secured.../secured/basketActorGET,或者创建一个带有 URL.../secured/add/1POST。在"Auth"选项卡下,您需要选择Basic Authentication并在其中添加凭据。