authenticateOrRejectWithChallenge

authenticateOrRejectWithChallenge

Signature

/**
 * The result of an HTTP authentication attempt is either the user object or
 * an HttpChallenge to present to the browser.
 */
type AuthenticationResult[+T] = Either[HttpChallenge, T]
def authenticateOrRejectWithChallenge[T](authenticator: Option[HttpCredentials]  Future[AuthenticationResult[T]]): AuthenticationDirective[T] 
def authenticateOrRejectWithChallenge[C <: HttpCredentials: ClassTag, T](
  authenticator: Option[C]  Future[AuthenticationResult[T]]): AuthenticationDirective[T] 

Description

Lifts an authenticator function into a directive.

This directive allows implementing the low level challange-response type of authentication that some services may require.

More details about challenge-response authentication are available in the RFC 2617, RFC 7616 and RFC 7617.

Example

val challenge = HttpChallenge("MyAuth", "MyRealm")

// your custom authentication logic:
def auth(creds: HttpCredentials): Boolean = true

def myUserPassAuthenticator(credentials: Option[HttpCredentials]): Future[AuthenticationResult[String]] =
  Future {
    credentials match {
      case Some(creds) if auth(creds) => Right("some-user-name-from-creds")
      case _                          => Left(challenge)
    }
  }

val route =
  Route.seal {
    path("secured") {
      authenticateOrRejectWithChallenge(myUserPassAuthenticator _) { userName =>
        complete("Authenticated!")
      }
    }
  }

// tests:
Get("/secured") ~> route ~> check {
  status shouldEqual StatusCodes.Unauthorized
  responseAs[String] shouldEqual "The resource requires authentication, which was not supplied with the request"
  header[`WWW-Authenticate`].get.challenges.head shouldEqual HttpChallenge("MyAuth", "MyRealm")
}

val validCredentials = BasicHttpCredentials("John", "p4ssw0rd")
Get("/secured") ~> addCredentials(validCredentials) ~> // adds Authorization header
  route ~> check {
    status shouldEqual StatusCodes.OK
    responseAs[String] shouldEqual "Authenticated!"
  }

Contents