I am trying a basic authentication on post request in spray.io 1.3.2 using authenticate directive. My code looks following:
val route: Route = {
pathPrefix("ato") {
pathPrefix("v1") {
path("orders" / "updateStatus") {
post {
authenticate(BasicAuth(userPasswordAuthenticator _, realm = "bd ato import api")) {
user =>
entity(as[String]) {e =>
complete {
s"Hello $e "
}
}
}
}
}
}
}
}
def userPasswordAuthenticator(userPass: Option[UserPass]): Future[Option[String]] =
Future {
if (userPass.exists(up => up.user == ato_import_v1_usr && up.pass == ato_import_v1_pwd)) Some("ato_v1")
else None
}
This works perfectly fine, authorized Status Ok 200, unauthorized 401. However when the order of directives is changed as follows:
val route: Route = {
pathPrefix("ato") {
pathPrefix("v1") {
authenticate(BasicAuth(userPasswordAuthenticator _, realm = "bd ato import api")) {
user =>
path("orders" / "updateStatus") {
post {
entity(as[String]) {e =>
complete {
s"Hello $e "
}
}
}
}
}
}
}
}
I am getting Status 405, HTTP method not allowed for unauthorized access. I am not sure why that happens. From certain point it make sense, path is not matched because of missing credentials etc.
Could someone please clarify that?
The reason why I wanted to put authorization at v1 level is that I wanted to make every version protected by different password. Is there a way how to achieve that? What is the best practice in chaining directives?
I would like to follow DRY principle.
Thanks