authenticateBasic • Akka HTTP (original) (raw)
Signature
type Authenticator[T] = Credentials => Option[T]
def authenticateBasic[T](realm: String, authenticator: Authenticator[T]): AuthenticationDirective[T]
Description
Wraps the inner route with Http Basic authentication support using a given Authenticator[T]Authenticator<T>
- function from Optional<ProvidedCredentials>
to Optional<T>
.
Provides support for handling HTTP Basic Authentication.
Given a function returning Some[T]
an Optional<T>
with a value upon successful authentication and None
an empty Optional<T>
otherwise, respectively applies the inner route or rejects the request with a AuthenticationFailedRejectionAuthenticationFailedRejection rejection, which by default is mapped to an 401 Unauthorized
response.
Longer-running authentication tasks (like looking up credentials in a database) should use the authenticateBasicAsync variant of this directive which allows it to run without blocking routing layer of Akka HTTP, freeing it for other requests.
Standard HTTP-based authentication which uses the WWW-Authenticate
header containing challenge data and AuthorizationAuthorization header for receiving credentials is implemented in authenticateOrRejectWithChallenge
.
See Credentials and password timing attacks for details about verifying the secret.
Warning
Make sure to use basic authentication only over SSL/TLS because credentials are transferred in plaintext.
Example
Scala
source`` def myUserPassAuthenticator(credentials: Credentials): Option[String] = credentials match { case p @ Credentials.Provided(id) if p.verify("p4ssw0rd") => Some(id) case _ => None }
val route = Route.seal { path("secured") { authenticateBasic(realm = "secure site", myUserPassAuthenticator) { userName => complete(s"The user is '$userName'") } } }
// 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("Basic", Some("secure site"), Map("charset" -> "UTF-8"))
}
val validCredentials = BasicHttpCredentials("John", "p4ssw0rd") Get("/secured") ~> addCredentials(validCredentials) ~> // adds Authorization header route ~> check { responseAs[String] shouldEqual "The user is 'John'" }
val invalidCredentials = BasicHttpCredentials("Peter", "pan")
Get("/secured") ~>
addCredentials(invalidCredentials) ~> // adds Authorization header
route ~> check {
status shouldEqual StatusCodes.Unauthorized
responseAs[String] shouldEqual "The supplied authentication is invalid"
header[WWW-Authenticate
].get.challenges.head shouldEqual HttpChallenge("Basic", Some("secure site"), Map("charset" -> "UTF-8"))
} ``
Java
source`import akka.http.javadsl.server.directives.SecurityDirectives.ProvidedCredentials;
import static akka.http.javadsl.server.Directives.authenticateBasic; import static akka.http.javadsl.server.Directives.complete; import static akka.http.javadsl.server.Directives.path;
final Function<Optional, Optional> myUserPassAuthenticator = credentials -> credentials.filter(c -> c.verify("p4ssw0rd")).map(ProvidedCredentials::identifier);
final Route route = path("secured", () -> authenticateBasic("secure site", myUserPassAuthenticator, userName -> complete("The user is '" + userName + "'") ) ).seal();
// 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");`
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.