extractClientIP

Signature

def extractClientIP: Directive1[RemoteAddress] 

Description

Provides the value of the X-Forwarded-For or X-Real-IP header. If neither of those is found it will fall back to the value of the synthetic RemoteAddress header (pekko.http.server.remote-address-header setting is on) or the value of the AttributeKeys.remoteAddress attribute (if the pekko.http.server.remote-address-attribute setting is on)

If no valid IP address is encountered, this extractor will return RemoteAddress.Unknown`.

Warning

Clients can send any values in these headers. If the client is not a trusted upstream, the IP address can be malicious. For sensitive operations use the AttributeKeys.remoteAddress attribute, or use the specific headers which are known to be set correctly by the infrastructure you do trust.

Example

Scala
Java
sourceval route = extractClientIP { ip =>
  complete("Client's ip is " + ip.toOption.map(_.getHostAddress).getOrElse("unknown"))
}

// tests:
Get("/").withHeaders(`X-Forwarded-For`(RemoteAddress(InetAddress.getByName("192.168.3.12")))) ~> route ~> check {
  responseAs[String] shouldEqual "Client's ip is 192.168.3.12"
}
sourcefinal Route route =
    extractClientIP(
        remoteAddr ->
            complete(
                "Client's IP is "
                    + remoteAddr
                        .getAddress()
                        .map(InetAddress::getHostAddress)
                        .orElseGet(() -> "unknown")));

// tests:
final String ip = "192.168.1.2";
final org.apache.pekko.http.javadsl.model.RemoteAddress remoteAddress =
    org.apache.pekko.http.javadsl.model.RemoteAddress.create(InetAddress.getByName(ip));

final HttpRequest request =
    HttpRequest.GET("/").addHeader(XForwardedFor.create(remoteAddress)); //

testRoute(route).run(request).assertEntity("Client's IP is " + ip);

testRoute(route).run(HttpRequest.GET("/")).assertEntity("Client's IP is unknown");