authenticateBasicAsync
Wraps the inner route with Http Basic authentication support using a given AsyncAuthenticator<T>
.
Description
This variant of the authenticateBasic directive returns a Future<Optional<T>>
which allows freeing up the routing layer of Akka HTTP, freeing it for other requests. It should be used whenever an authentication is expected to take a longer amount of time (e.g. looking up the user in a database).
In case the returned option is an empty Optional
the request is rejected with a AuthenticationFailedRejection
, which by default is mapped to an 401 Unauthorized
response.
Standard HTTP-based authentication which uses the WWW-Authenticate
header containing challenge data and Authorization
header for receiving credentials is implemented in subclasses of HttpAuthenticator
.
See Credentials and password timing attacks for details about verifying the secret.
Make sure to use basic authentication only over SSL/TLS because credentials are transferred in plaintext.
Example
final Function<Optional<ProvidedCredentials>, CompletionStage<Optional<String>>> myUserPassAuthenticator = opt -> {
if (opt.filter(c -> (c != null) && c.verify("p4ssw0rd")).isPresent()) {
return CompletableFuture.completedFuture(Optional.of(opt.get().identifier()));
} else {
return CompletableFuture.completedFuture(Optional.empty());
}
};
final Route route = path("secured", () ->
authenticateBasicAsync("secure site", myUserPassAuthenticator, userName ->
complete("The user is '" + userName + "'")
)
).seal(system(), materializer());
// tests:
testRoute(route).run(HttpRequest.GET("/secured"))
.assertStatusCode(StatusCodes.UNAUTHORIZED)
.assertEntity("The resource requires authentication, which was not supplied with the request")
.assertHeaderExists("WWW-Authenticate", "Basic realm=\"secure site\",charset=UTF-8");
final HttpCredentials validCredentials =
BasicHttpCredentials.createBasicHttpCredentials("John", "p4ssw0rd");
testRoute(route).run(HttpRequest.GET("/secured").addCredentials(validCredentials))
.assertEntity("The user is 'John'");
final HttpCredentials invalidCredentials =
BasicHttpCredentials.createBasicHttpCredentials("Peter", "pan");
testRoute(route).run(HttpRequest.GET("/secured").addCredentials(invalidCredentials))
.assertStatusCode(StatusCodes.UNAUTHORIZED)
.assertEntity("The supplied authentication is invalid")
.assertHeaderExists("WWW-Authenticate", "Basic realm=\"secure site\",charset=UTF-8");