scala - 使用 REST Http 进行 Akka 身份验证
问题描述
我正在使用 Akka 基本身份验证和 scala 测试 Json HTTP 路由。但是这些路线不能按需要工作。这是代码
首先,安全路线不适用于邮递员 BasicAuth。我需要添加一个电子邮件“secured/test@test.com”来触发登录操作。其次,子路由篮子演员根本不工作。邮递员说未知路线。那么如何使用 Postman BasicAuth Http Header 进行这项工作?我必须发送什么样的请求只是“安全或与电子邮件和密码一起发送。其次我怎样才能使子路由basketActor / add工作。
~ 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
}
所以我的预期结果应该是用户调用安全路由登录,然后他可以访问 basketActor 路由。但是现在该路线无法访问,并且安全路线也无法正常工作
解决方案
这就是 Akka HTTP 中基本身份验证的工作方式:
HTTP 请求中的Authorization
标头用于基本身份验证,它包含使用base64
编码编码的用户名和密码。该authenticateBasic
路由将从标头中提取此信息以创建一个Credentials
对象,然后将其传递给您的myUserPassAuthenticator
方法。此方法应检查用户名和密码是否匹配,如果成功,则应返回代表系统中该用户的对象,否则返回None
失败。
第二个(curried)参数authenticateBasic
是一个函数,它接受用户数据并返回一个Route
. 因此,在您的情况下,参数email
将包含. 此函数应返回包含所有需要身份验证的路径的路由。id
myUserPassAuthenticator
重要的是要意识到没有使用基本身份验证“登录”的概念。只有正确或不正确的身份验证凭据。(如果您想要登录/注销语义,您需要迁移到基于令牌的身份验证机制)。
因此,要使您的路由正常工作,您需要将查找用户 ID 的逻辑移入myUserPassAuthenticator
并返回user
对象作为结果。碰巧你可以只返回结果,find
因为这已经返回了一个Option[User]
.
您还需要确保所有经过身份验证的路由都在authenticateBasic
路由内。目前basketActor
和add
路由处于同一级别,因此未经过身份验证。
示例路线如下所示。我用过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 进行测试,您需要GET
使用 URL创建 a.../secured
或.../secured/basketActor
,或 POST
使用URL 创建 a .../secured/add/1
。在Auth
选项卡下,您需要在Basic Authentication
那里选择并添加凭据。
推荐阅读
- android - 科尔多瓦 bluetoothSerial.discoverUnpaired 不会在 android 10 中发出值
- windows - 是否有任何方法可以使用 shell 命令获取 Windows 设备中所有已安装应用程序的详细信息
- ms-access - 使用 MS Access 查询(BOM 资源管理器的排序)
- sql - 如何在 SQL Server SQL Query 中进行多个左连接
- javascript - JavaScript 循环将数据附加到 formData - 递增变量显示与 formData 中的每个循环相同
- kivy - 在 Kivy 中使用构建器
- reactjs - 带有嵌套查询结果的 ApolloClient v3 fetchMore
- java - 为keycloak角色动态定义springboot antmatcher
- python-3.x - 根据数据框中的条件拆分列
- python - Excel中的for循环Python OpenPyXL