Low level directive – unless you’re sure you need to be working on this low-level you might instead want to try the handleRejections directive which provides a nicer DSL for building rejection handlers.
Transforms rejections from the inner route with an immutable.Seq[Rejection] => RouteResult function.a Function<Iterable<Rejection>, RouteResult>. A RouteResultRouteResult is either a Complete(HttpResponse(...))Complete containing the HttpResponseHttpResponse or a Rejected(rejections).Rejected containing the rejections.
Note
To learn more about how and why rejections work read the Rejections section of the documentation.
sourceval authRejectionsToNothingToSeeHere = recoverRejections { rejections =>if(rejections.exists(_.isInstanceOf[AuthenticationFailedRejection]))Complete(HttpResponse(entity ="Nothing to see here, move along."))elseif(rejections ==Nil)// see "Empty Rejections" for more detailsComplete(HttpResponse(StatusCodes.NotFound, entity ="Literally nothing to see here."))elseRejected(rejections)}
val neverAuth:Authenticator[String]= creds =>None
val alwaysAuth:Authenticator[String]= creds =>Some("id")
val route =
authRejectionsToNothingToSeeHere {
pathPrefix("auth"){
concat(
path("never"){
authenticateBasic("my-realm", neverAuth){ user =>
complete("Welcome to the bat-cave!")}},
path("always"){
authenticateBasic("my-realm", alwaysAuth){ user =>
complete("Welcome to the secret place!")}})}}// tests:Get("/auth/never")~> route ~> check {
status shouldEqual StatusCodes.OK
responseAs[String] shouldEqual "Nothing to see here, move along."}Get("/auth/always")~> route ~> check {
status shouldEqual StatusCodes.OK
responseAs[String] shouldEqual "Welcome to the secret place!"}Get("/auth/does_not_exist")~> route ~> check {
status shouldEqual StatusCodes.NotFound
responseAs[String] shouldEqual "Literally nothing to see here."}
sourceimport akka.http.javadsl.server.directives.SecurityDirectives.ProvidedCredentials;importstatic akka.http.javadsl.server.Directives.authenticateBasic;importstatic akka.http.javadsl.server.Directives.recoverRejections;finalFunction<Optional<ProvidedCredentials>,Optional<Object>> neverAuth =
creds ->Optional.empty();finalFunction<Optional<ProvidedCredentials>,Optional<Object>> alwaysAuth =
creds ->Optional.of("id");finalRoute originalRoute = pathPrefix("auth",()->Directives.concat(
path("never",()->
authenticateBasic("my-realm", neverAuth, obj -> complete("Welcome to the bat-cave!"))),
path("always",()->
authenticateBasic("my-realm", alwaysAuth, obj -> complete("Welcome to the secret place!")))));finalFunction<Iterable<Rejection>,Boolean> existsAuthenticationFailedRejection =
rejections ->StreamSupport.stream(rejections.spliterator(),false).anyMatch(r -> r instanceofAuthenticationFailedRejection);finalRoute route = recoverRejections(rejections ->{if(existsAuthenticationFailedRejection.apply(rejections)){returnRouteResults.complete(HttpResponse.create().withEntity("Nothing to see here, move along."));}elseif(!rejections.iterator().hasNext()){// see "Empty Rejections" for more detailsreturnRouteResults.complete(HttpResponse.create().withStatus(StatusCodes.NOT_FOUND).withEntity("Literally nothing to see here."));}else{returnRouteResults.rejected(rejections);}},()-> originalRoute);// tests:
testRoute(route).run(HttpRequest.GET("/auth/never")).assertStatusCode(StatusCodes.OK).assertEntity("Nothing to see here, move along.");
testRoute(route).run(HttpRequest.GET("/auth/always")).assertStatusCode(StatusCodes.OK).assertEntity("Welcome to the secret place!");
testRoute(route).run(HttpRequest.GET("/auth/does_not_exist")).assertStatusCode(StatusCodes.NOT_FOUND).assertEntity("Literally nothing to see here.");