authenticateOrRejectWithChallenge

authenticateOrRejectWithChallenge

Lifts an authenticator function into a directive.

§Description

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

  1. final HttpChallenge challenge = HttpChallenge.create("MyAuth", "MyRealm");
  2.  
  3. // your custom authentication logic:
  4. final Function<HttpCredentials, Boolean> auth = credentials -> true;
  5.  
  6. final Function<Optional<HttpCredentials>, CompletionStage<Either<HttpChallenge, String>>> myUserPassAuthenticator =
  7. opt -> {
  8. if (opt.isPresent() && auth.apply(opt.get())) {
  9. return CompletableFuture.completedFuture(Right.apply("some-user-name-from-creds"));
  10. } else {
  11. return CompletableFuture.completedFuture(Left.apply(challenge));
  12. }
  13. };
  14.  
  15. final Route route = path("secured", () ->
  16. authenticateOrRejectWithChallenge(myUserPassAuthenticator, userName ->
  17. complete("Authenticated!")
  18. )
  19. ).seal(system(), materializer());
  20.  
  21. // tests:
  22. testRoute(route).run(HttpRequest.GET("/secured"))
  23. .assertStatusCode(StatusCodes.UNAUTHORIZED)
  24. .assertEntity("The resource requires authentication, which was not supplied with the request")
  25. .assertHeaderExists("WWW-Authenticate", "MyAuth realm=\"MyRealm\"");
  26.  
  27. final HttpCredentials validCredentials =
  28. BasicHttpCredentials.createBasicHttpCredentials("John", "p4ssw0rd");
  29. testRoute(route).run(HttpRequest.GET("/secured").addCredentials(validCredentials))
  30. .assertStatusCode(StatusCodes.OK)
  31. .assertEntity("Authenticated!");