spray authenticate directive returns different HTTP status codes

260 Views Asked by At

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

0

There are 0 best solutions below