[SMX4-999]enhance cxf-ws-security-osgi example to leverage cxf JAASLoginInterceptor to authenticate against karaf default jaas configuration
git-svn-id: https://svn.apache.org/repos/asf/servicemix/smx4/features/trunk@1210334 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/examples/cxf/cxf-ws-security-osgi/README.txt b/examples/cxf/cxf-ws-security-osgi/README.txt
index edb07b9..135e0ed 100644
--- a/examples/cxf/cxf-ws-security-osgi/README.txt
+++ b/examples/cxf/cxf-ws-security-osgi/README.txt
@@ -21,7 +21,8 @@
Purpose
-------
Create a web service with CXF using WS-SECURITY and expose it through the OSGi HTTP
-Service.
+Service, then it will leverage cxf JAASLoginInterceptor to authenticate against karaf
+default jaas configuration.
Explanation
@@ -33,12 +34,10 @@
The beans.xml file, located in the src/main/resources/META-INF/spring
directory:
-1. Imports the configuration files needed to enable CXF and OSGi work
- together.
-2. Configures the web service endpoint as follows:
+1. Configures the web service endpoint as follows:
- <jaxws:endpoint id="helloWorld"
+ <jaxws:endpoint id="helloWorld"
implementor="org.apache.servicemix.examples.cxf.HelloWorldImpl"
address="/HelloWorldSecurity">
<jaxws:inInterceptors>
@@ -47,15 +46,20 @@
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordText"/>
- <entry key="passwordCallbackRef">
- <ref bean="myPasswordCallback"/>
- </entry>
-
</map>
</constructor-arg>
</bean>
+ <ref bean="authenticationInterceptor"/>
</jaxws:inInterceptors>
+ <jaxws:properties>
+ <entry key="ws-security.validate.token" value="false"/>
+ </jaxws:properties>
</jaxws:endpoint>
+ <bean id="authenticationInterceptor" class="org.apache.cxf.interceptor.security.JAASLoginInterceptor">
+ <property name="contextName" value="karaf"/>
+ </bean>
+
+This will leverage cxf JAASLoginInterceptor to authenticate against karaf default jaas configuration through property contextName, which store username/password/role in SMX_HOME/etc/users.properties, to run this example, need add joe=password in etc/users.properties. Users can easily change to use other jaas context(JDBC,LDAP etc) as described from http://karaf.apache.org/manual/2.2.4/developers-guide/security-framework.html.
Prerequisites for Running the Example
@@ -140,15 +144,10 @@
mvn compile exec:java
- If the client request is successful, a response similar to the
- following should appear in the ServiceMix console:
-
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Body><ns2:sayHiResponse xmlns:ns2="http://cxf.examples.
- servicemix.apache.org/"><return>Hello John Doe</return>
- </ns2:sayHiResponse>
- </soap:Body>
- </soap:Envelope>
+ If the client request is successful,
+ it will print out
+ Hello ffang
+ in the ServiceMix console:
Changing /cxf servlet alias
diff --git a/examples/cxf/cxf-ws-security-osgi/pom.xml b/examples/cxf/cxf-ws-security-osgi/pom.xml
index 20849ce..f2912ef 100644
--- a/examples/cxf/cxf-ws-security-osgi/pom.xml
+++ b/examples/cxf/cxf-ws-security-osgi/pom.xml
@@ -31,7 +31,6 @@
<packaging>bundle</packaging>
<name>Apache ServiceMix :: Features :: Examples :: CXF WS-Security OSGi</name>
<description>CXF example using WS-Security</description>
-
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
@@ -45,6 +44,21 @@
<groupId>org.apache.ws.security</groupId>
<artifactId>wss4j</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-ws-security</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ <version>${cxf.version}</version>
+ </dependency>
</dependencies>
<build>
@@ -59,14 +73,16 @@
<Import-Package>
javax.jws,
javax.xml.bind.annotation,
- javax.xml.namespace,
javax.wsdl,
+ org.apache.cxf.ws.security.wss4j,
org.springframework.beans.factory.config,
javax.security.auth.callback,
- org.apache.cxf.ws.security.wss4j,
org.apache.ws.security,
+ org.apache.commons.logging,
org.apache.servicemix.util,
- org.apache.ws.security.processor
+ org.apache.ws.security.processor,
+ org.apache.cxf.interceptor.security,
+ org.apache.cxf, org.apache.cxf.endpoint, org.apache.cxf.frontend, org.apache.cxf.interceptor, org.apache.cxf.jaxws, org.apache.cxf.message, org.apache.cxf.phase
</Import-Package>
<Export-Package>org.apache.servicemix.examples.cxf</Export-Package>
</instructions>
diff --git a/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/Client.java b/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/Client.java
index 8890c39..b79abad 100644
--- a/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/Client.java
+++ b/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/Client.java
@@ -16,14 +16,14 @@
*/
package org.apache.servicemix.examples.cxf;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.URLConnection;
-import org.apache.servicemix.util.FileUtil;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.frontend.ClientProxy;
+import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
+import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
+
public class Client{
public static void main(String[] args) {
@@ -35,20 +35,21 @@
}
public void sendRequest() throws Exception {
- URLConnection connection = new URL("http://localhost:8181/cxf/HelloWorldSecurity")
- .openConnection();
- connection.setDoInput(true);
- connection.setDoOutput(true);
- OutputStream os = connection.getOutputStream();
- // Post the request file.
- InputStream fis = getClass().getClassLoader().getResourceAsStream("org/apache/servicemix/examples/cxf/request.xml");
- FileUtil.copyInputStream(fis, os);
- // Read the response.
- InputStream is = connection.getInputStream();
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- FileUtil.copyInputStream(is, baos);
- System.out.println("the response is =====>");
- System.out.println(baos.toString());
+ JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
+ factory.setServiceClass(HelloWorld.class);
+ factory.setAddress("http://localhost:8181/cxf/HelloWorldSecurity");
+ HelloWorld client = (HelloWorld) factory.create();
+
+ Map<String, Object> outProps = new HashMap<String, Object>();
+ outProps.put("action", "UsernameToken");
+
+ //add a CustomerSecurityInterceptor for client side to init wss4j staff
+ //retrieve and set user/password, users can easily add this interceptor
+ //through spring configuration also
+ ClientProxy.getClient(client).getOutInterceptors().add(new CustomerSecurityInterceptor());
+ ClientProxy.getClient(client).getOutInterceptors().add(new WSS4JOutInterceptor());
+ String ret = client.sayHi("ffang");
+ System.out.println(ret);
}
}
diff --git a/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/ServerPasswordCallback.java b/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/ClientPasswordCallback.java
old mode 100644
new mode 100755
similarity index 95%
rename from examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/ServerPasswordCallback.java
rename to examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/ClientPasswordCallback.java
index c7f6cf9..56f95e4
--- a/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/ServerPasswordCallback.java
+++ b/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/ClientPasswordCallback.java
@@ -25,7 +25,7 @@
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;
-public class ServerPasswordCallback implements CallbackHandler {
+public class ClientPasswordCallback implements CallbackHandler {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
diff --git a/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/CustomerSecurityInterceptor.java b/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/CustomerSecurityInterceptor.java
new file mode 100644
index 0000000..04944a1
--- /dev/null
+++ b/examples/cxf/cxf-ws-security-osgi/src/main/java/org/apache/servicemix/examples/cxf/CustomerSecurityInterceptor.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.servicemix.examples.cxf;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.interceptor.Interceptor;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
+
+public class CustomerSecurityInterceptor extends AbstractPhaseInterceptor<Message> {
+
+ public CustomerSecurityInterceptor() {
+ super(Phase.SETUP);
+ }
+
+ public void handleMessage(Message message) throws Fault {
+ Map<String, Object> outProps = new HashMap<String, Object>();
+ outProps.put("action", "UsernameToken");
+
+ outProps.put("passwordType", "PasswordText");
+ outProps.put("user", "joe");
+ outProps.put("passwordCallbackClass", "org.apache.servicemix.examples.cxf.ClientPasswordCallback");
+ for (Interceptor inteceptor : message.getInterceptorChain()) {
+ //set properties for WSS4JOutInterceptor
+ if (inteceptor.getClass().getName().equals("org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor")) {
+ ((WSS4JOutInterceptor)inteceptor).setProperties(outProps);
+ }
+ }
+ }
+
+
+}
diff --git a/examples/cxf/cxf-ws-security-osgi/src/main/resources/META-INF/spring/beans.xml b/examples/cxf/cxf-ws-security-osgi/src/main/resources/META-INF/spring/beans.xml
index 0625d46..eb990b5 100755
--- a/examples/cxf/cxf-ws-security-osgi/src/main/resources/META-INF/spring/beans.xml
+++ b/examples/cxf/cxf-ws-security-osgi/src/main/resources/META-INF/spring/beans.xml
@@ -26,8 +26,6 @@
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
- <bean id="myPasswordCallback" class="org.apache.servicemix.examples.cxf.ServerPasswordCallback"/>
-
<jaxws:endpoint id="helloWorld"
implementor="org.apache.servicemix.examples.cxf.HelloWorldImpl"
address="/HelloWorldSecurity">
@@ -37,15 +35,18 @@
<map>
<entry key="action" value="UsernameToken"/>
<entry key="passwordType" value="PasswordText"/>
- <entry key="passwordCallbackRef">
- <ref bean="myPasswordCallback"/>
- </entry>
-
</map>
</constructor-arg>
</bean>
+ <ref bean="authenticationInterceptor"/>
</jaxws:inInterceptors>
+ <jaxws:properties>
+ <entry key="ws-security.validate.token" value="false"/>
+ </jaxws:properties>
</jaxws:endpoint>
+ <bean id="authenticationInterceptor" class="org.apache.cxf.interceptor.security.JAASLoginInterceptor">
+ <property name="contextName" value="karaf"/>
+ </bean>
</beans>
<!-- END SNIPPET: beans -->
diff --git a/examples/cxf/cxf-ws-security-osgi/src/main/resources/org/apache/servicemix/examples/cxf/request.xml b/examples/cxf/cxf-ws-security-osgi/src/main/resources/org/apache/servicemix/examples/cxf/request.xml
deleted file mode 100755
index 7f00050..0000000
--- a/examples/cxf/cxf-ws-security-osgi/src/main/resources/org/apache/servicemix/examples/cxf/request.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
- <soap:Header>
- <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
- <wsse:UsernameToken >
- <wsse:Username>joe</wsse:Username>
- <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</wsse:Password>
- </wsse:UsernameToken>
- </wsse:Security>
- </soap:Header>
- <soap:Body>
- <ns2:sayHi xmlns:ns2="http://cxf.examples.servicemix.apache.org/">
- <arg0>John Doe</arg0>
- </ns2:sayHi>
- </soap:Body>
-</soap:Envelope>