You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pp...@apache.org on 2022/11/28 08:02:15 UTC
[camel-quarkus] 01/06: Add CXF WS-SecurityPolicy test
This is an automated email from the ASF dual-hosted git repository.
ppalaga pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
commit b913f4f68cd455a76245c96e95a85d5e922f9663
Author: Peter Palaga <pp...@redhat.com>
AuthorDate: Fri Oct 28 22:41:15 2022 +0200
Add CXF WS-SecurityPolicy test
---
.../cxf-soap/cxf-soap-ws-security-server/pom.xml | 229 +++++++++++++++++++++
.../server/it/PasswordCallbackHandler.java | 55 +++++
.../server/it/WsSecurityPolicyServerRoutes.java | 54 +++++
.../server/it/WssSecurityPolicyHelloService.java | 27 +++
.../it/WssSecurityPolicyHelloServiceImpl.java | 39 ++++
.../{application.properties => alice.properties} | 7 +-
.../src/main/resources/application.properties | 2 +
.../{application.properties => bob.properties} | 7 +-
.../src/main/resources/encrypt-sign-policy.xml | 75 +++++++
.../server/it/CxfWssSecurityPolicyServerIT.java | 24 +++
.../server/it/CxfWssSecurityPolicyServerTest.java | 214 +++++++++++++++++++
pom.xml | 1 +
poms/build-parent-it/pom.xml | 5 +
13 files changed, 735 insertions(+), 4 deletions(-)
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/pom.xml b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/pom.xml
index 8e2c12d8a0..8a6d83f6ee 100644
--- a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/pom.xml
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/pom.xml
@@ -67,6 +67,235 @@
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>keytool-maven-plugin</artifactId>
+ <configuration>
+ <keypass>password</keypass>
+ <validity>365</validity>
+ <keyalg>RSA</keyalg>
+ <storepass>password</storepass>
+ </configuration>
+ <executions>
+ <execution>
+ <id>generate-cxfca-keypair</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>clean</goal>
+ <goal>generateKeyPair</goal>
+ </goals>
+ <configuration>
+ <alias>cxfca</alias>
+ <dname>CN=cxfca, OU=eng, O=apache.org</dname>
+ <exts>
+ <ext>bc:c=ca:true,pathlen:2147483647</ext>
+ <ext>IssuerAlternativeName=DNS:NOT-FOR-PRODUCTION-USE</ext>
+ </exts>
+ <keystore>${project.build.outputDirectory}/cxfca.jks</keystore>
+ </configuration>
+ </execution>
+ <execution>
+ <id>export-cxfca-certificate</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>exportCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>cxfca</alias>
+ <keystore>${project.build.outputDirectory}/cxfca.jks</keystore>
+ <rfc>true</rfc>
+ <file>${project.build.outputDirectory}/cxfca.pem</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-alice-keypair</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>clean</goal>
+ <goal>generateKeyPair</goal>
+ </goals>
+ <configuration>
+ <alias>alice</alias>
+ <dname>CN=alice, OU=eng, O=apache.org</dname>
+ <exts>
+ <ext>IssuerAlternativeName=DNS:NOT-FOR-PRODUCTION-USE</ext>
+ <ext>SubjectAlternativeName=DNS:localhost,IP:127.0.0.1</ext>
+ </exts>
+ <keystore>${project.build.outputDirectory}/alice.jks</keystore>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-bob-keypair</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>clean</goal>
+ <goal>generateKeyPair</goal>
+ </goals>
+ <configuration>
+ <alias>bob</alias>
+ <dname>CN=bob, OU=eng, O=apache.org</dname>
+ <exts>
+ <ext>IssuerAlternativeName=DNS:NOT-FOR-PRODUCTION-USE</ext>
+ <ext>SubjectAlternativeName=DNS:localhost,IP:127.0.0.1</ext>
+ </exts>
+ <keystore>${project.build.outputDirectory}/bob.jks</keystore>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-alice-certificate-request</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generateCertificateRequest</goal>
+ </goals>
+ <configuration>
+ <alias>alice</alias>
+ <keystore>${project.build.outputDirectory}/alice.jks</keystore>
+ <file>${project.build.outputDirectory}/alice.csr</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-alice-certificate</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generateCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>cxfca</alias>
+ <keystore>${project.build.outputDirectory}/cxfca.jks</keystore>
+ <rfc>true</rfc>
+ <infile>${project.build.outputDirectory}/alice.csr</infile>
+ <outfile>${project.build.outputDirectory}/alice.pem</outfile>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-bob-certificate-request</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generateCertificateRequest</goal>
+ </goals>
+ <configuration>
+ <alias>bob</alias>
+ <keystore>${project.build.outputDirectory}/bob.jks</keystore>
+ <file>${project.build.outputDirectory}/bob.csr</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>generate-bob-certificate</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>generateCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>cxfca</alias>
+ <keystore>${project.build.outputDirectory}/cxfca.jks</keystore>
+ <rfc>true</rfc>
+ <infile>${project.build.outputDirectory}/bob.csr</infile>
+ <outfile>${project.build.outputDirectory}/bob.pem</outfile>
+ </configuration>
+ </execution>
+ <execution>
+ <id>import-cxfca-certificate-to-alice</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>importCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>cxfca</alias>
+ <trustcacerts>true</trustcacerts>
+ <noprompt>true</noprompt>
+ <keystore>${project.build.outputDirectory}/alice.jks</keystore>
+ <file>${project.build.outputDirectory}/cxfca.pem</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>import-cxfca-certificate-to-bob</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>importCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>cxfca</alias>
+ <trustcacerts>true</trustcacerts>
+ <noprompt>true</noprompt>
+ <keystore>${project.build.outputDirectory}/bob.jks</keystore>
+ <file>${project.build.outputDirectory}/cxfca.pem</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>import-alice-certificate</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>importCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>alice</alias>
+ <trustcacerts>true</trustcacerts>
+ <noprompt>true</noprompt>
+ <keystore>${project.build.outputDirectory}/alice.jks</keystore>
+ <file>${project.build.outputDirectory}/alice.pem</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>import-bob-certificate</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>importCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>bob</alias>
+ <trustcacerts>true</trustcacerts>
+ <noprompt>true</noprompt>
+ <keystore>${project.build.outputDirectory}/bob.jks</keystore>
+ <file>${project.build.outputDirectory}/bob.pem</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>import-bob-certificate-to-alice</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>importCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>bob</alias>
+ <trustcacerts>true</trustcacerts>
+ <noprompt>true</noprompt>
+ <keystore>${project.build.outputDirectory}/alice.jks</keystore>
+ <file>${project.build.outputDirectory}/bob.pem</file>
+ </configuration>
+ </execution>
+ <execution>
+ <id>import-alice-certificate-to-bob</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>importCertificate</goal>
+ </goals>
+ <configuration>
+ <alias>alice</alias>
+ <trustcacerts>true</trustcacerts>
+ <noprompt>true</noprompt>
+ <keystore>${project.build.outputDirectory}/bob.jks</keystore>
+ <file>${project.build.outputDirectory}/alice.pem</file>
+ </configuration>
+ </execution>
+<!-- Uncomment execution block below for local testing -->
+<!-- <execution>-->
+<!-- <id>list</id>-->
+<!-- <phase>generate-sources</phase>-->
+<!-- <goals>-->
+<!-- <goal>list</goal>-->
+<!-- </goals>-->
+<!-- <configuration>-->
+<!-- <verbose>true</verbose>-->
+<!-- <keystore>${project.build.outputDirectory}/bob.jks</keystore>-->
+<!-- </configuration>-->
+<!-- </execution>-->
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
<profiles>
<profile>
<id>native</id>
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/PasswordCallbackHandler.java b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/PasswordCallbackHandler.java
new file mode 100644
index 0000000000..73f713a064
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/PasswordCallbackHandler.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+import io.quarkus.runtime.annotations.RegisterForReflection;
+import org.apache.wss4j.common.ext.WSPasswordCallback;
+
+@RegisterForReflection(methods = false, fields = false)
+public class PasswordCallbackHandler implements CallbackHandler {
+
+ private final Map<String, String> passwords;
+
+ public PasswordCallbackHandler() {
+ this.passwords = Map.of(
+ "alice", "password",
+ "bob", "password");
+ }
+
+ /**
+ * It attempts to get the password from the private alias/passwords map.
+ */
+ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+
+ String pass = passwords.get(pc.getIdentifier());
+ if (pass != null) {
+ pc.setPassword(pass);
+ return;
+ }
+ }
+ }
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WsSecurityPolicyServerRoutes.java b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WsSecurityPolicyServerRoutes.java
new file mode 100644
index 0000000000..f130f41a63
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WsSecurityPolicyServerRoutes.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.inject.Produces;
+import javax.inject.Named;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.cxf.jaxws.CxfEndpoint;
+import org.apache.cxf.ext.logging.LoggingFeature;
+
+@ApplicationScoped
+public class WsSecurityPolicyServerRoutes extends RouteBuilder {
+
+ @Override
+ public void configure() {
+
+ from("cxf:bean:wsSecurityPolicyHelloService?dataFormat=POJO")
+ .log("exchange: ${exchange}")
+ .setBody(exchange -> "Secure good morning " + exchange.getMessage().getBody(String.class));
+
+ }
+
+ @Produces
+ @ApplicationScoped
+ @Named
+ CxfEndpoint wsSecurityPolicyHelloService() {
+ final CxfEndpoint result = new CxfEndpoint();
+ result.setServiceClass(WssSecurityPolicyHelloServiceImpl.class);
+ result.setAddress("/security-policy-hello");
+
+ final LoggingFeature lf = new LoggingFeature();
+ lf.setPrettyLogging(true);
+ result.getFeatures().add(lf);
+
+ return result;
+ }
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WssSecurityPolicyHelloService.java b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WssSecurityPolicyHelloService.java
new file mode 100644
index 0000000000..29f2595678
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WssSecurityPolicyHelloService.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+
+@WebService(targetNamespace = "https://quarkiverse.github.io/quarkiverse-docs/quarkus-cxf/ws-securitypolicy")
+public interface WssSecurityPolicyHelloService {
+
+ @WebMethod
+ String sayHello(String name);
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WssSecurityPolicyHelloServiceImpl.java b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WssSecurityPolicyHelloServiceImpl.java
new file mode 100644
index 0000000000..632d27451e
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/WssSecurityPolicyHelloServiceImpl.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it;
+
+import javax.jws.WebService;
+
+import org.apache.cxf.annotations.EndpointProperties;
+import org.apache.cxf.annotations.EndpointProperty;
+import org.apache.cxf.annotations.Policy;
+
+@WebService(portName = "EncryptSecurityServicePort", serviceName = "WssSecurityPolicyHelloService", targetNamespace = "https://quarkiverse.github.io/quarkiverse-docs/quarkus-cxf/ws-securitypolicy", endpointInterface = "org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it.WssSecurityPolicyHelloService")
+@Policy(placement = Policy.Placement.BINDING, uri = "encrypt-sign-policy.xml")
+@EndpointProperties(value = {
+ @EndpointProperty(key = "ws-security.signature.properties", value = "bob.properties"),
+ @EndpointProperty(key = "ws-security.encryption.properties", value = "bob.properties"),
+ @EndpointProperty(key = "ws-security.signature.username", value = "bob"),
+ @EndpointProperty(key = "ws-security.encryption.username", value = "alice"),
+ @EndpointProperty(key = "ws-security.callback-handler", value = "org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it.PasswordCallbackHandler")
+})
+public class WssSecurityPolicyHelloServiceImpl implements WssSecurityPolicyHelloService {
+
+ public String sayHello(String name) {
+ return "Secure Hello " + name + "!";
+ }
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/alice.properties
similarity index 75%
copy from integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
copy to integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/alice.properties
index 2eaadf41fb..b562e89eec 100644
--- a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/alice.properties
@@ -14,5 +14,8 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-
-quarkus.cxf.path=/soapservice
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=password
+org.apache.ws.security.crypto.merlin.keystore.alias=alice
+org.apache.ws.security.crypto.merlin.file=alice.jks
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
index 2eaadf41fb..7ca94be086 100644
--- a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
@@ -16,3 +16,5 @@
## ---------------------------------------------------------------------------
quarkus.cxf.path=/soapservice
+
+quarkus.native.resources.includes=bob.properties,alice.properties,alice.jks,bob.jks,encrypt-sign-policy.xml
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/bob.properties
similarity index 75%
copy from integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
copy to integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/bob.properties
index 2eaadf41fb..4b4e1bd8a5 100644
--- a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/application.properties
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/bob.properties
@@ -14,5 +14,8 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-
-quarkus.cxf.path=/soapservice
+org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+org.apache.ws.security.crypto.merlin.keystore.type=jks
+org.apache.ws.security.crypto.merlin.keystore.password=password
+org.apache.ws.security.crypto.merlin.keystore.alias=bob
+org.apache.ws.security.crypto.merlin.file=bob.jks
\ No newline at end of file
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/encrypt-sign-policy.xml b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/encrypt-sign-policy.xml
new file mode 100644
index 0000000000..2eba7ca542
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/main/resources/encrypt-sign-policy.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<wsp:Policy wsu:Id="SecurityServiceEncryptThenSignPolicy"
+ xmlns:wsp="http://www.w3.org/ns/ws-policy"
+ xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
+ xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:AsymmetricBinding xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
+ <wsp:Policy>
+ <sp:InitiatorToken>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
+ <wsp:Policy>
+ <sp:WssX509V1Token11/>
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:InitiatorToken>
+ <sp:RecipientToken>
+ <wsp:Policy>
+ <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
+ <wsp:Policy>
+ <sp:WssX509V1Token11/>
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:RecipientToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256/>
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Strict/>
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp/>
+ <sp:ProtectTokens/>
+ <sp:OnlySignEntireHeadersAndBody/>
+ <sp:EncryptBeforeSigning/>
+ </wsp:Policy>
+ </sp:AsymmetricBinding>
+ <sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body/>
+ </sp:SignedParts>
+ <sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <sp:Body/>
+ </sp:EncryptedParts>
+ <sp:Wss10 xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
+ <wsp:Policy>
+ <sp:MustSupportRefIssuerSerial/>
+ </wsp:Policy>
+ </sp:Wss10>
+ </wsp:All>
+ </wsp:ExactlyOne>
+</wsp:Policy>
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/test/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/CxfWssSecurityPolicyServerIT.java b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/test/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/CxfWssSecurityPolicyServerIT.java
new file mode 100644
index 0000000000..64e2996405
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/test/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/CxfWssSecurityPolicyServerIT.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class CxfWssSecurityPolicyServerIT extends CxfWssSecurityPolicyServerTest {
+
+}
diff --git a/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/test/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/CxfWssSecurityPolicyServerTest.java b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/test/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/CxfWssSecurityPolicyServerTest.java
new file mode 100644
index 0000000000..7a0fd487bb
--- /dev/null
+++ b/integration-test-groups/cxf-soap/cxf-soap-ws-security-server/src/test/java/org/apache/camel/quarkus/component/cxf/soap/securitypolicy/server/it/CxfWssSecurityPolicyServerTest.java
@@ -0,0 +1,214 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.cxf.soap.securitypolicy.server.it;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.xml.ws.BindingProvider;
+
+import io.quarkiverse.cxf.test.QuarkusCxfClientTestUtil;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.config.RestAssuredConfig;
+import org.apache.cxf.ws.security.SecurityConstants;
+import org.assertj.core.api.Assertions;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matchers;
+import org.junit.jupiter.api.Test;
+
+import static io.quarkiverse.cxf.test.QuarkusCxfClientTestUtil.anyNs;
+import static io.restassured.RestAssured.given;
+
+@QuarkusTest
+public class CxfWssSecurityPolicyServerTest {
+
+ @Test
+ void encrypetdSigned() throws IOException {
+ WssSecurityPolicyHelloService client = getPlainClient();
+
+ Map<String, Object> ctx = ((BindingProvider) client).getRequestContext();
+ ctx.put(SecurityConstants.CALLBACK_HANDLER, new PasswordCallbackHandler());
+ ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
+ Thread.currentThread().getContextClassLoader().getResource("alice.properties"));
+ ctx.put(SecurityConstants.SIGNATURE_USERNAME, "alice");
+ ctx.put(SecurityConstants.ENCRYPT_USERNAME, "bob");
+ ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
+ Thread.currentThread().getContextClassLoader().getResource("alice.properties"));
+
+ Assertions.assertThat(client.sayHello("foo")).isEqualTo("Secure Hello foo!");
+ }
+
+ @Test
+ void noSecurityConfig() throws IOException {
+ WssSecurityPolicyHelloService client = getPlainClient();
+ /* Make sure that it fails properly when called without a password */
+ Assertions.assertThatExceptionOfType(javax.xml.ws.soap.SOAPFaultException.class)
+ .isThrownBy(() -> client.sayHello("bar"))
+ .withMessage(
+ "A encryption username needs to be declared.");
+ }
+
+ @Test
+ void unencryptedUnsigned() throws IOException {
+ final String SOAP_REQUEST = "<soap:Envelope\n"
+ + " xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
+ + " <soap:Header/>\n"
+ + " <soap:Body>\n"
+ + " <ns2:sayHello\n"
+ + " xmlns:ns2=\"https://quarkiverse.github.io/quarkiverse-docs/quarkus-cxf/ws-securitypolicy\"/>\n"
+ + " </soap:Body>\n"
+ + "</soap:Envelope>";
+
+ given()
+ .body(SOAP_REQUEST)
+ .when().post(QuarkusCxfClientTestUtil.getEndpointUrl(getPlainClient()))
+ .then()
+ .statusCode(500)
+ .body(
+ Matchers.containsString(
+ "X509Token: The received token does not match the token inclusion requirement"),
+ Matchers.containsString("Soap Body is not SIGNED"),
+ Matchers.containsString("Soap Body is not ENCRYPTED"));
+ }
+
+ @Test
+ void fakeSigned() throws IOException {
+ /*
+ * A syntactically correct signature, however signed with a different certificate with a different CA than
+ * deployed on the server
+ */
+ final String SOAP_REQUEST = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\n"
+ + " <soap:Header>\n"
+ + " <wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" soap:mustUnderstand=\"1\">\n"
+ + " <wsse:BinarySecurityToken EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\" ValueType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3\" wsu:Id=\"X509-53f34474-bcdf-424c-bb90-61b11537cb3f\">MIICnjCCAgmgAwIBAgIEAvQDETALBgkqhkiG9w0BAQUwMzETMBEGA1UEChMKYXBhY2hlLm9yZzEMMAoGA1UECxMDZW5nMQ4wDAYDVQQDEwVjeGZjYTAiGA8yMDIyMDkxOTEyMDA0NFoYDzk5OTkxMjMxMjM1OTU5WjAzMRMwEQYDV [...]
+ + " <wsu:Timestamp wsu:Id=\"TS-ccfad22e-b376-4349-a625-8896061d6cfd\">\n"
+ + " <wsu:Created>2022-09-19T12:00:51.226Z</wsu:Created>\n"
+ + " <wsu:Expires>2022-09-19T12:05:51.226Z</wsu:Expires>\n"
+ + " </wsu:Timestamp>\n"
+ + " <xenc:EncryptedKey xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\" Id=\"EK-d77a377b-2dab-4045-ac3e-ea53d7609158\">\n"
+ + " <xenc:EncryptionMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p\" />\n"
+ + " <ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n"
+ + " <wsse:SecurityTokenReference>\n"
+ + " <ds:X509Data>\n"
+ + " <ds:X509IssuerSerial>\n"
+ + " <ds:X509IssuerName>CN=cxfca,OU=eng,O=apache.org</ds:X509IssuerName>\n"
+ + " <ds:X509SerialNumber>49546002</ds:X509SerialNumber>\n"
+ + " </ds:X509IssuerSerial>\n"
+ + " </ds:X509Data>\n"
+ + " </wsse:SecurityTokenReference>\n"
+ + " </ds:KeyInfo>\n"
+ + " <xenc:CipherData>\n"
+ + " <xenc:CipherValue>AaHIPkC7xEAxE1WS8u1lwEp8+VVAFhg61EqUyKAxi4jUPRdYXwa1J7jWQ28Z86preNMLJ7CUfv1stESHCziuZtjoundejV588aN7bymBYwN24zu2LRgUQ49PjADInrMX39gqwv9EtgixEUCwkaCS48/ihY7v7Vb7+cXnrpqAcVrxqF8Y0g2/FfN/k/6IZASGORzHKXcszQM9y+QyDzKZvw9ukSj7oDDBNUhrtrhb2KslOC5UukhSkPQwxrIHAlGCmbTDiohhYjEJCzBE9bb1/+0//7vFx/kPuhr8cRI7wg7WAhl8MIUHvv40TD8FoCo8JH1IJSPfuTs+fcLUSSRMBg==</xenc:CipherValue>\n"
+ + " </xenc:CipherData>\n"
+ + " </xenc:EncryptedKey>\n"
+ + " <ds:Signature xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" Id=\"SIG-d48e583c-d310-428b-9541-1c589934b261\">\n"
+ + " <ds:SignedInfo>\n"
+ + " <ds:CanonicalizationMethod Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\">\n"
+ + " <ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"soap\" />\n"
+ + " </ds:CanonicalizationMethod>\n"
+ + " <ds:SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" />\n"
+ + " <ds:Reference URI=\"#TS-ccfad22e-b376-4349-a625-8896061d6cfd\">\n"
+ + " <ds:Transforms>\n"
+ + " <ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\">\n"
+ + " <ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"wsse soap\" />\n"
+ + " </ds:Transform>\n"
+ + " </ds:Transforms>\n"
+ + " <ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" />\n"
+ + " <ds:DigestValue>pdXC+DtlPCX25Cb1NipeNUOCwl4=</ds:DigestValue>\n"
+ + " </ds:Reference>\n"
+ + " <ds:Reference URI=\"#_551cb542-d0fe-4fb8-8e11-e0d7dfe47210\">\n"
+ + " <ds:Transforms>\n"
+ + " <ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\" />\n"
+ + " </ds:Transforms>\n"
+ + " <ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" />\n"
+ + " <ds:DigestValue>LcxYrZK9si3cDmaUurS3dXHKWEI=</ds:DigestValue>\n"
+ + " </ds:Reference>\n"
+ + " <ds:Reference URI=\"#X509-53f34474-bcdf-424c-bb90-61b11537cb3f\">\n"
+ + " <ds:Transforms>\n"
+ + " <ds:Transform Algorithm=\"http://www.w3.org/2001/10/xml-exc-c14n#\">\n"
+ + " <ec:InclusiveNamespaces xmlns:ec=\"http://www.w3.org/2001/10/xml-exc-c14n#\" PrefixList=\"soap\" />\n"
+ + " </ds:Transform>\n"
+ + " </ds:Transforms>\n"
+ + " <ds:DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" />\n"
+ + " <ds:DigestValue>vDSN64D/q4EjUCBczlIA0IHzxLc=</ds:DigestValue>\n"
+ + " </ds:Reference>\n"
+ + " </ds:SignedInfo>\n"
+ + " <ds:SignatureValue>d2qb4hRGLF/IOJHDA+hiMpil3hEArczDMEq2Q8bzKy74BbAWu54D2d3JWfMceq3/zHNvG4ND7zOd/0o2TPV05i9k5wVya+FOwlP7ibQ/Yy9lkTNhRMHCL94Es63i7AKPwTcTiGJtYQERcUcp4kXaE/fuRlpD4tv2IfnR+ss1jraOqEtgci//xpjWVUBV4vN5Rpolc10QOYUQGjG/ZqaOgT9QHEnm/WN2ZcFMwOrVlc066ifbbHVnJfS/A+VSjoP2FEnNcmRcG8RrNZc4/LOMVCiCnaldriqTrjtCnF29s0Kwtv00P931Yjb4vPFeLIdw6C+zL8/A3q+TOQ4mH9B4MQ==</ds:SignatureValue>\n"
+ + " <ds:KeyInfo Id=\"KI-2bd212e6-4be5-4d39-b69f-b147f6a540fd\">\n"
+ + " <wsse:SecurityTokenReference wsu:Id=\"STR-4e477765-3f65-4910-93be-9e1fe3d129a0\">\n"
+ + " <wsse:Reference URI=\"#X509-53f34474-bcdf-424c-bb90-61b11537cb3f\" ValueType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3\" />\n"
+ + " </wsse:SecurityTokenReference>\n"
+ + " </ds:KeyInfo>\n"
+ + " </ds:Signature>\n"
+ + " <xenc:ReferenceList xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\">\n"
+ + " <xenc:DataReference URI=\"#ED-ed7e9c30-7b36-452d-ac71-85fa51c60986\" />\n"
+ + " </xenc:ReferenceList>\n"
+ + " </wsse:Security>\n"
+ + " </soap:Header>\n"
+ + " <soap:Body xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" wsu:Id=\"_551cb542-d0fe-4fb8-8e11-e0d7dfe47210\">\n"
+ + " <xenc:EncryptedData xmlns:xenc=\"http://www.w3.org/2001/04/xmlenc#\" Id=\"ED-ed7e9c30-7b36-452d-ac71-85fa51c60986\" Type=\"http://www.w3.org/2001/04/xmlenc#Content\">\n"
+ + " <xenc:EncryptionMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#aes256-cbc\" />\n"
+ + " <ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\">\n"
+ + " <wsse:SecurityTokenReference xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsse11=\"http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd\" wsse11:TokenType=\"http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey\">\n"
+ + " <wsse:Reference URI=\"#EK-d77a377b-2dab-4045-ac3e-ea53d7609158\" />\n"
+ + " </wsse:SecurityTokenReference>\n"
+ + " </ds:KeyInfo>\n"
+ + " <xenc:CipherData>\n"
+ + " <xenc:CipherValue>21+PWStmrSWFm9QgE0A6hGMEsTAoKFmhLzX2w7MY2B8KCQNeke5eEW7IBXPQySCNgPw7q1+LmOajM/2AmLsKp2q5ZOXxtOStEkJLxbZ4LCsKtv5rfFiWGTl8d7OS8hHGZLVl1wfEG0n/k7FqCw9WRuKfZFqIsQA06yfQPELVU1hUh1K/vEPGGFol4oa1wzVi</xenc:CipherValue>\n"
+ + " </xenc:CipherData>\n"
+ + " </xenc:EncryptedData>\n"
+ + " </soap:Body>\n"
+ + "</soap:Envelope>";
+
+ given()
+ .body(SOAP_REQUEST)
+ .when().post(QuarkusCxfClientTestUtil.getEndpointUrl(getPlainClient()))
+ .then()
+ .statusCode(500)
+ .body(
+ Matchers.containsString(
+ "A security error was encountered when verifying the message"));
+ }
+
+ /**
+ * Make sure the policy was included
+ */
+ @Test
+ void wsdl() {
+ RestAssuredConfig config = RestAssured.config();
+ config.getXmlConfig().namespaceAware(false);
+ given()
+ .config(config)
+ .when().get(QuarkusCxfClientTestUtil.getEndpointUrl(getPlainClient()) + "?wsdl")
+ .then()
+ .statusCode(200)
+ .body(
+ Matchers.hasXPath(
+ anyNs("definitions", "Policy")
+ + "/@*[local-name() = 'Id']",
+ CoreMatchers.is("SecurityServiceEncryptThenSignPolicy")));
+ }
+
+ WssSecurityPolicyHelloService getPlainClient() {
+ return QuarkusCxfClientTestUtil.getClient(
+ "https://quarkiverse.github.io/quarkiverse-docs/quarkus-cxf/ws-securitypolicy",
+ WssSecurityPolicyHelloService.class,
+ "/soapservice/security-policy-hello");
+ }
+}
diff --git a/pom.xml b/pom.xml
index 5a564c35b4..0cfd408081 100644
--- a/pom.xml
+++ b/pom.xml
@@ -180,6 +180,7 @@
<groovy.version>3.0.8</groovy.version>
<impsort-maven-plugin.version>1.7.0</impsort-maven-plugin.version>
<jandex-maven-plugin.version>1.0.8</jandex-maven-plugin.version>
+ <keytool-maven-plugin.version>1.6</keytool-maven-plugin.version>
<mycila-license.version>3.0</mycila-license.version>
<maven-assembly-plugin.version>3.1.1</maven-assembly-plugin.version>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
diff --git a/poms/build-parent-it/pom.xml b/poms/build-parent-it/pom.xml
index 5439455ee9..05d6127be7 100644
--- a/poms/build-parent-it/pom.xml
+++ b/poms/build-parent-it/pom.xml
@@ -107,6 +107,11 @@
<artifactId>camel-servicenow-maven-plugin</artifactId>
<version>${camel.version}</version>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>keytool-maven-plugin</artifactId>
+ <version>${keytool-maven-plugin.version}</version>
+ </plugin>
</plugins>
</pluginManagement>
<plugins>