I'm testing Json HTTP Routes with Akka Basic Authentication and scala. But the routes don't work as needed. Here is the code
First the secured route is not working with postman BasicAuth. I need to add an email"secured/test@test.com" to trigger the logged in action. Second the subroute basketactor is not working at all. Postman says unknown Route. So how can i make this work with Postman BasicAuth Http Header? What kind of request do i have to send just "secured or with email and password together. Second how can i make the subroutes basketActor/add work.
~ 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
}
So my expected result should be the user calls the secured Route logs in and then he can access the basketActor route. But now the route is not accessible and the secured route is also not working
This is how Basic Authentication works in Akka HTTP:
The Authorization
header in an HTTP Request is used for Basic Authentication, and it contains a username and password encoded using base64
encoding. The authenticateBasic
route will extract this information from the header to create a Credentials
object, and then pass this to your myUserPassAuthenticator
method. This method should check that the username and password match and if it succeeds it should return an object representing that user in your system, or return None
on failure.
The second (curried) argument to authenticateBasic
is a function that takes the user data and returns a Route
. So in your case the email
argument will contain the id
value returned by myUserPassAuthenticator
. This function should return a route that contains all the paths that require authentication.
It is important to realise that there is no concept of being "logged in" with Basic Authentication. There are just authentication credentials that are either correct or incorrect. (If you want to have login/logout semantics you need to move to a token-based authentication mechanism).
So to make your routes work you need to move the logic that looks-up a user ID into myUserPassAuthenticator
and return the user
object as the result. As it happens you can just return the result of find
because this already returns an Option[User]
.
You also need to make sure that all the authenticated routes are inside the authenticateBasic
route. Currently the basketActor
and add
routes are at the same level and therefore are not authenticated.
A sample route would look like this. I have used concat
rather than ~
as I think it is clearer.
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")
}
}
)
}
}
Note that the user ID (email address) is not in the URL, it is in the request in the Basic Authentication
header.
To test this with Postman you need to go create a GET
with the URL .../secured
or .../secured/basketActor
, or a POST
with the URL .../secured/add/1
. Under the Auth
tab you need to select Basic Authentication
and add the credentials there.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.