Skip to content

Commit

Permalink
Allow configuration of proxy authentication via application.properties
Browse files Browse the repository at this point in the history
…fix #988
  • Loading branch information
ppalaga committed Aug 31, 2023
1 parent 864e8a2 commit 44937c9
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@ quarkus.cxf.client.clientWithRuntimeInitializedPayload.native.runtime-initialize
quarkus.native.additional-build-args = --initialize-at-run-time=io.quarkiverse.cxf.client.it.rtinit.Operands\\,io.quarkiverse.cxf.client.it.rtinit.Result

quarkus.cxf.codegen.wsdl2java.includes = wsdl/*.wsdl

quarkus.cxf.client.proxiedCalculator.wsdl = wsdl/CalculatorService.wsdl
quarkus.cxf.client.proxiedCalculator.client-endpoint-url = ${cxf.it.calculator.hostNameUri}/calculator-ws/CalculatorService
quarkus.cxf.client.proxiedCalculator.proxy-server = ${cxf.it.calculator.proxy.host}
quarkus.cxf.client.proxiedCalculator.proxy-server-port = ${cxf.it.calculator.proxy.port}
quarkus.cxf.client.proxiedCalculator.proxy-username = ${cxf.it.calculator.proxy.user}
quarkus.cxf.client.proxiedCalculator.proxy-password = ${cxf.it.calculator.proxy.password}
34 changes: 34 additions & 0 deletions docs/modules/ROOT/pages/includes/quarkus-cxf.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1295,4 +1295,38 @@ endif::add-copy-button-to-env-var[]
`http`, `socks`
|`http`


a| [[quarkus-cxf_quarkus.cxf.client.-clients-.proxy-username]]`link:#quarkus-cxf_quarkus.cxf.client.-clients-.proxy-username[quarkus.cxf.client."clients".proxy-username]`


[.description]
--
Username for the proxy authentication

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_CXF_CLIENT__CLIENTS__PROXY_USERNAME+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_CXF_CLIENT__CLIENTS__PROXY_USERNAME+++`
endif::add-copy-button-to-env-var[]
--|string
|


a| [[quarkus-cxf_quarkus.cxf.client.-clients-.proxy-password]]`link:#quarkus-cxf_quarkus.cxf.client.-clients-.proxy-password[quarkus.cxf.client."clients".proxy-password]`


[.description]
--
Password for the proxy authentication

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_CXF_CLIENT__CLIENTS__PROXY_PASSWORD+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_CXF_CLIENT__CLIENTS__PROXY_PASSWORD+++`
endif::add-copy-button-to-env-var[]
--|string
|

|===
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,14 @@ public class CXFClientInfo {
* Specifies the type of the proxy server. Can be either HTTP or SOCKS.
*/
private ProxyServerType proxyServerType;
/**
* Username for the proxy authentication
*/
private String proxyUsername;
/**
* Password for the proxy authentication
*/
private String proxyPassword;

public CXFClientInfo() {
}
Expand Down Expand Up @@ -212,6 +220,8 @@ public CXFClientInfo(CXFClientInfo other) {
this.proxyServerPort = other.proxyServerPort;
this.nonProxyHosts = other.nonProxyHosts;
this.proxyServerType = other.proxyServerType;
this.proxyUsername = other.proxyUsername;
this.proxyPassword = other.proxyPassword;
}

public CXFClientInfo withConfig(CxfClientConfig config) {
Expand Down Expand Up @@ -248,6 +258,8 @@ public CXFClientInfo withConfig(CxfClientConfig config) {
this.proxyServerPort = config.proxyServerPort.orElse(null);
this.nonProxyHosts = config.nonProxyHosts.orElse(null);
this.proxyServerType = config.proxyServerType;
this.proxyUsername = config.proxyUsername.orElse(null);
this.proxyPassword = config.proxyPassword.orElse(null);
return this;
}

Expand Down Expand Up @@ -440,4 +452,12 @@ public String getNonProxyHosts() {
public ProxyServerType getProxyServerType() {
return proxyServerType;
}

public String getProxyUsername() {
return proxyUsername;
}

public String getProxyPassword() {
return proxyPassword;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -225,22 +225,22 @@ public class CxfClientConfig {
* also be used to optimize for different SOAP stacks.
*/
@ConfigItem
protected Optional<String> browserType;
public Optional<String> browserType;
/**
* Specifies the URL of a decoupled endpoint for the receipt of responses over a separate provider->consumer connection.
*/
@ConfigItem
protected Optional<String> decoupledEndpoint;
public Optional<String> decoupledEndpoint;
/**
* Specifies the address of proxy server if one is used.
*/
@ConfigItem
protected Optional<String> proxyServer;
public Optional<String> proxyServer;
/**
* Specifies the port number used by the proxy server.
*/
@ConfigItem
protected Optional<Integer> proxyServerPort;
public Optional<Integer> proxyServerPort;
/**
* Specifies the list of hostnames that will not use the proxy configuration.
* Examples of value:
Expand All @@ -249,11 +249,21 @@ public class CxfClientConfig {
* * "localhost|www.google.*|*.apache.org" -> It's also possible to use a pattern-like value
*/
@ConfigItem
protected Optional<String> nonProxyHosts;
public Optional<String> nonProxyHosts;
/**
* Specifies the type of the proxy server. Can be either HTTP or SOCKS.
*/
@ConfigItem(defaultValue = "HTTP")
protected ProxyServerType proxyServerType;
public ProxyServerType proxyServerType;
/**
* Username for the proxy authentication
*/
@ConfigItem
public Optional<String> proxyUsername;
/**
* Password for the proxy authentication
*/
@ConfigItem
public Optional<String> proxyPassword;

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import jakarta.xml.ws.BindingProvider;
import jakarta.xml.ws.handler.Handler;

import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.feature.Feature;
import org.apache.cxf.frontend.ClientProxy;
Expand Down Expand Up @@ -208,6 +209,16 @@ private Object produceCxfClient(CXFClientInfo cxfClientInfo) {
}
}
policy.setProxyServerType(cxfClientInfo.getProxyServerType());

final String proxyUsername = cxfClientInfo.getProxyUsername();
if (proxyUsername != null) {
final String proxyPassword = cxfClientInfo.getProxyPassword();
final ProxyAuthorizationPolicy proxyAuth = new ProxyAuthorizationPolicy();
proxyAuth.setUserName(proxyUsername);
proxyAuth.setPassword(proxyPassword);
httpConduit.setProxyAuthorization(proxyAuth);
}

return result;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ public class CxfClientResource {
@CXFClient("clientWithRuntimeInitializedPayload") // name used in application.properties
ClientWithRuntimeInitializedPayload clientWithRuntimeInitializedPayload;

@CXFClient("proxiedCalculator")
CalculatorService proxiedCalculator;

@GET
@Path("/calculator/{client}/multiply")
@Produces(MediaType.TEXT_PLAIN)
Expand Down Expand Up @@ -130,6 +133,8 @@ private CalculatorService getClient(String client) {
return myFaultyCalculator;
case "mySkewedCalculator":
return mySkewedCalculator;
case "proxiedCalculator":
return proxiedCalculator;
default:
throw new IllegalStateException("Unexpected client key " + client);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@ quarkus.cxf.client.clientWithRuntimeInitializedPayload.native.runtime-initialize
quarkus.native.additional-build-args = --initialize-at-run-time=io.quarkiverse.cxf.client.it.rtinit.Operands\\,io.quarkiverse.cxf.client.it.rtinit.Result

quarkus.cxf.codegen.wsdl2java.includes = wsdl/*.wsdl

quarkus.cxf.client.proxiedCalculator.wsdl = wsdl/CalculatorService.wsdl
quarkus.cxf.client.proxiedCalculator.client-endpoint-url = ${cxf.it.calculator.hostNameUri}/calculator-ws/CalculatorService
quarkus.cxf.client.proxiedCalculator.proxy-server = ${cxf.it.calculator.proxy.host}
quarkus.cxf.client.proxiedCalculator.proxy-server-port = ${cxf.it.calculator.proxy.port}
quarkus.cxf.client.proxiedCalculator.proxy-username = ${cxf.it.calculator.proxy.user}
quarkus.cxf.client.proxiedCalculator.proxy-password = ${cxf.it.calculator.proxy.password}
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ void multiply(String clientKey) {
.body(is(String.valueOf(expected)));
}

/**
* Test whether a client with proxy and proxy auth set works properly
*
* @param clientKey
*/
@Test
void multiplyProxy() {
RestAssured.given()
.queryParam("a", 4)
.queryParam("b", 5)
.get("/cxf/client/calculator/proxiedCalculator/multiply")
.then()
.statusCode(200)
.body(is(String.valueOf(20)));
}

/**
* Test whether passing a complex object to the client and receiving a complex object from the client works properly
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,42 @@

package io.quarkiverse.cxf.client.it;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.Network;
import org.testcontainers.containers.wait.strategy.Wait;

import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;

public class CxfClientTestResource implements QuarkusTestResourceLifecycleManager {

private static final int WILDFLY_PORT = 8080;
private static final int PROXY_PORT = 8080;
private static final String SOAP_SERVICE_HOST = "calculator-service";
private static final int SOAP_SERVICE_PORT = 8080;
private GenericContainer<?> proxy;
private GenericContainer<?> calculatorContainer;
private Network network;
private GenericContainer<?> skewedCalculatorContainer;

@Override
public Map<String, String> start() {

network = Network.newNetwork();

final String PROXY_USER = "proxyuser";
final String PROXY_PASSWORD = UUID.randomUUID().toString();

final String BASIC_AUTH_USER = "tester";
final String BASIC_AUTH_PASSWORD = UUID.randomUUID().toString();

try {
calculatorContainer = new GenericContainer<>("quay.io/l2x6/calculator-ws:1.3")
.withExposedPorts(WILDFLY_PORT)
.withExposedPorts(SOAP_SERVICE_PORT)
.withNetworkAliases(SOAP_SERVICE_HOST)
.withNetwork(network)
.withEnv("BASIC_AUTH_USER", BASIC_AUTH_USER)
.withEnv("BASIC_AUTH_PASSWORD", BASIC_AUTH_PASSWORD)
.waitingFor(Wait.forHttp("/calculator-ws/CalculatorService?wsdl"));
Expand All @@ -48,19 +61,37 @@ public Map<String, String> start() {

skewedCalculatorContainer = new GenericContainer<>("quay.io/l2x6/calculator-ws:1.3")
.withEnv("ADD_TO_RESULT", "100")
.withExposedPorts(WILDFLY_PORT)
.withExposedPorts(SOAP_SERVICE_PORT)
.waitingFor(Wait.forHttp("/calculator-ws/CalculatorService?wsdl"));

skewedCalculatorContainer.start();

return Map.of(
"cxf.it.calculator.baseUri",
"http://" + calculatorContainer.getHost() + ":" + calculatorContainer.getMappedPort(WILDFLY_PORT),
"cxf.it.skewed-calculator.baseUri",
proxy = new GenericContainer<>("mitmproxy/mitmproxy:10.0.0")
.withCommand("mitmdump", "--set", "proxyauth=" + PROXY_USER + ":" + PROXY_PASSWORD)
.withExposedPorts(PROXY_PORT)
.withNetwork(network)
.waitingFor(Wait.forListeningPort());
proxy.start();

final Map<String, String> props = new LinkedHashMap<>();
props.put("cxf.it.calculator.baseUri",
"http://" + calculatorContainer.getHost() + ":" + calculatorContainer.getMappedPort(SOAP_SERVICE_PORT));
props.put("cxf.it.skewed-calculator.baseUri",
"http://" + skewedCalculatorContainer.getHost() + ":"
+ skewedCalculatorContainer.getMappedPort(WILDFLY_PORT),
"cxf.it.calculator.auth.basic.user", BASIC_AUTH_USER,
"cxf.it.calculator.auth.basic.password", BASIC_AUTH_PASSWORD);
+ skewedCalculatorContainer.getMappedPort(SOAP_SERVICE_PORT));
props.put("cxf.it.calculator.auth.basic.user", BASIC_AUTH_USER);
props.put("cxf.it.calculator.auth.basic.password", BASIC_AUTH_PASSWORD);

props.put(
"cxf.it.calculator.hostNameUri",
"http://" + SOAP_SERVICE_HOST + ":" + SOAP_SERVICE_PORT);

props.put("cxf.it.calculator.proxy.host", proxy.getHost());
props.put("cxf.it.calculator.proxy.port", String.valueOf(proxy.getMappedPort(PROXY_PORT)));
props.put("cxf.it.calculator.proxy.user", PROXY_USER);
props.put("cxf.it.calculator.proxy.password", PROXY_PASSWORD);

return props;
} catch (Exception e) {
throw new RuntimeException(e);
}
Expand All @@ -82,5 +113,19 @@ public void stop() {
} catch (Exception e) {
// ignored
}
try {
if (proxy != null) {
proxy.stop();
}
} catch (Exception e) {
// ignored
}
try {
if (network != null) {
network.close();
}
} catch (Exception e) {
// ignored
}
}
}

0 comments on commit 44937c9

Please sign in to comment.