Author: alessio.soldano(a)jboss.com
Date: 2012-10-15 04:51:56 -0400 (Mon, 15 Oct 2012)
New Revision: 16874
Modified:
stack/cxf/trunk/modules/dist/src/main/doc/Book_Info.xml
stack/cxf/trunk/modules/dist/src/main/doc/Revision_History.xml
stack/cxf/trunk/modules/dist/src/main/doc/chapter-2-Quick_Start.xml
stack/cxf/trunk/modules/dist/src/main/doc/chapter-3-JAX_WS_User_Guide.xml
stack/cxf/trunk/modules/dist/src/main/doc/chapter-4-JAX_WS_Tools.xml
stack/cxf/trunk/modules/dist/src/main/doc/chapter-5-Advanced_User_Guide.xml
Log:
Updating documentation
Modified: stack/cxf/trunk/modules/dist/src/main/doc/Book_Info.xml
===================================================================
--- stack/cxf/trunk/modules/dist/src/main/doc/Book_Info.xml 2012-10-12 14:07:42 UTC (rev
16873)
+++ stack/cxf/trunk/modules/dist/src/main/doc/Book_Info.xml 2012-10-15 08:51:56 UTC (rev
16874)
@@ -4,7 +4,7 @@
<title>JBoss Web Services Documentation</title>
<!--<subtitle></subtitle>-->
<productname>JBossWS - CXF</productname>
- <productnumber>4.0.0.GA</productnumber>
+ <productnumber>4.1.0.Final</productnumber>
<!-- <edition>ToDo</edition>
<pubsnumber>ToDo</pubsnumber> -->
<abstract>
Modified: stack/cxf/trunk/modules/dist/src/main/doc/Revision_History.xml
===================================================================
--- stack/cxf/trunk/modules/dist/src/main/doc/Revision_History.xml 2012-10-12 14:07:42 UTC
(rev 16873)
+++ stack/cxf/trunk/modules/dist/src/main/doc/Revision_History.xml 2012-10-15 08:51:56 UTC
(rev 16874)
@@ -46,6 +46,20 @@
</simplelist>
</revdescription>
</revision>
+ <revision>
+ <revnumber>4.1.0</revnumber>
+ <date>Mon Oct 15 2012</date>
+ <author>
+ <firstname>Alessio</firstname>
+ <surname>Soldano</surname>
+ <email>alessio.soldano(a)jboss.com</email>
+ </author>
+ <revdescription>
+ <simplelist>
+ <member>JBossWS-CXF 4.1.0 documentation</member>
+ </simplelist>
+ </revdescription>
+ </revision>
</revhistory>
</simpara>
</appendix>
Modified: stack/cxf/trunk/modules/dist/src/main/doc/chapter-2-Quick_Start.xml
===================================================================
--- stack/cxf/trunk/modules/dist/src/main/doc/chapter-2-Quick_Start.xml 2012-10-12
14:07:42 UTC (rev 16873)
+++ stack/cxf/trunk/modules/dist/src/main/doc/chapter-2-Quick_Start.xml 2012-10-15
08:51:56 UTC (rev 16874)
@@ -71,7 +71,8 @@
<title>Implementing the service</title>
<informalexample>
- <programlisting>package
org.jboss.test.ws.jaxws.samples.retail.profile;
+ <programlisting>
+package org.jboss.test.ws.jaxws.samples.retail.profile;
import javax.ejb.Stateless;
import javax.jws.WebService;
@@ -90,7 +91,8 @@
public DiscountResponse getCustomerDiscount(DiscountRequest request) {
return new DiscountResponse(request.getCustomer(), 10.00);
}
-}</programlisting>
+}
+</programlisting>
</informalexample>
<informalexample>
<programlisting>1. We are using a stateless session bean
implementation
@@ -105,7 +107,8 @@
<para>The method parameters and return values are going to represent our
XML payload and thus require being compatible with JAXB2. Actually you wouldn't need
any JAXB annotations for this particular example, because JAXB relies on meaningful
defaults. For the sake of documentation we put the more important ones here.</para>
<para>Take a look at the request parameter:</para>
<informalexample>
- <programlisting>package
org.jboss.test.ws.jaxws.samples.retail.profile;
+ <programlisting>
+package org.jboss.test.ws.jaxws.samples.retail.profile;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@@ -138,7 +141,8 @@
this.customer = value;
}
-}</programlisting>
+}
+</programlisting>
</informalexample>
<informalexample>
<programlisting>1. In this case we use @XmlType to specify an XML
complex type name and override the namespace.</programlisting>
@@ -324,7 +328,8 @@
<title>Constructing a service stub</title>
<para>Web service clients make use of a service stubs that hide the
details of a remote web service invocation. To a client application a WS invocation just
looks like an invocation of any other business component. In this case the service
endpoint interface acts as the business interface. JAX-WS does use a service factory
class to construct this as particular service stub:</para>
<informalexample>
- <programlisting>import javax.xml.ws.Service;
+ <programlisting>
+import javax.xml.ws.Service;
[...]
Service service = Service.create( (1)
new
URL("http://example.org/service?wsdl"),
@@ -332,7 +337,8 @@
);
ProfileMgmt profileMgmt = service.getPort(ProfileMgmt.class); (2)
-// do something with the service stub here...
(3)</programlisting>
+// do something with the service stub here... (3)
+</programlisting>
</informalexample>
<orderedlist>
<listitem>
@@ -349,6 +355,158 @@
</listitem>
</orderedlist>
</section>
+ <section
id="sid-3735860_QuickStart-Resolvingdependenciesandrunningtheclient">
+
+ <title>Resolving dependencies and running the client</title>
+ <para>In order for successfully running a WS client application, a
classloader needs to be properly setup to include the JBossWS components and its required
transitive dependencies. Depending on the environment the client is meant to be run in,
this might imply adding some jars to the classpath, or adding some artifact dependencies
to the maven dependency tree, etc. Moreover, even for simply developing a client, users
might need to resolve proper dependencies (e.g. to setup their IDE).</para>
+ <para>Below you find some options for resolving dependencies and running a
WS client using the JBossWS libraries:</para>
+ <section id="sid-3735860_QuickStart-Mavenproject">
+
+ <title>Maven project</title>
+ <para>
+ The JBossWS project is composed of multiple Maven artifacts that can be used
to declare dependencies in user Maven projects. In particular, the
+ <code>
+ <ulink
url="https://repository.jboss.org/nexus/content/groups/public-jboss/...
+ </code>
+ and
+ <ulink
url="https://repository.jboss.org/nexus/content/groups/public-jboss/...
+ <code>org.jboss.ws.native:jbossws-native-client</code>
+ </ulink>
+ artifacts can be used for getting the whole jbossws client dependency trees
for the JBossWS-CXF and JBossWS-Native stacks. Users should simply add a dependency on
+ <emphasis role="strong">one</emphasis>
+ of them (depending on the JBossWS stack in use) to their Maven project.
+ </para>
+ <para>
+ If you're running the client out of container, It's also recommended
to properly setup JAXWS implementation endorsing, to use the JBossWS implementation of
JAXWS API instead of relying on the implementation coming with the JDK; this is usually
done by copying the
+ <code>
+ <ulink
url="https://repository.jboss.org/nexus/content/groups/public-jboss/...
+ </code>
+ (JBossWS-CXF stack)
+ <emphasis role="strong">or</emphasis>
+ <code>
+ <ulink
url="https://repository.jboss.org/nexus/content/groups/public-jboss/...
+ </code>
+ (JBossWS-Native stack) jar into a local directory (e.g.
+ <emphasis
role="italics">project.build.directory/endorsed</emphasis>
+ ) and then using that for compiling and running sources, for setting the
+ <emphasis role="italics">java.endorsed.dirs</emphasis>
+ system property into the maven-surefire-plugin, etc:
+ </para>
+ <informalexample>
+ <programlisting><project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
[
http://maven.apache.org/maven-v4_0_0.xsd]">
+ ...
+ <build>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>create-endorsed-dir</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+ <artifactItem>
+
<groupId>org.jboss.spec.javax.xml.ws</groupId>
+
<artifactId>jboss-jaxws-api_2.2_spec</artifactId>
+ <type>jar</type>
+
<outputDirectory>${project.build.directory}/endorsed</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+
<groupId>org.jboss.spec.javax.xml.bind</groupId>
+
<artifactId>jboss-jaxb-api_2.2_spec</artifactId>
+ <type>jar</type>
+
<outputDirectory>${project.build.directory}/endorsed</outputDirectory>
+ </artifactItem>
+ <artifactItem>
+ <groupId>org.jboss.ws.cxf</groupId>
+
<artifactId>jbossws-cxf-factories</artifactId>
+ <type>jar</type>
+
<outputDirectory>${project.build.directory}/endorsed</outputDirectory>
+ </artifactItem>
+ </artifactItems>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <showDeprecation>false</showDeprecation>
+ <compilerArguments>
+
<endorseddirs>${project.build.directory}/endorsed</endorseddirs>
+ </compilerArguments>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+
<argLine>-Djava.endorsed.dirs=${project.build.directory}/endorsed</argLine>
+ ...
+ </configuration>
+ ...
+ </plugin>
+ ...
+ </plugins>
+ ...
+ </build>
+...
+</project>
+</programlisting>
+ </informalexample>
+ <important>
+ <para>Endorsing of JAXWS API jar is used to force a API level different
from the one included in the JDK. E.g. JAXWS 2.2 on JDK 1.6, or JAXWS 2.1 on JDK 1.7,
etc.</para>
+ </important>
+ </section>
+ <section id="sid-3735860_QuickStart-JBossModulesenvironment">
+
+ <title>JBoss Modules environment</title>
+ <para>
+ An interesting approach for running a WS client is to leverage JBoss Modules,
basically getting a classloading environment equivalent to the server container WS
endpoints are run in. This is achieved by using the
+ <emphasis role="italics">jboss-modules.jar</emphasis>
+ coming with AS 7 as follows:
+ </para>
+ <informalexample>
+ <programlisting>java -jar $JBOSS_HOME/jboss-modules.jar -mp
$JBOSS_HOME/modules -jar client.jar</programlisting>
+ </informalexample>
+ <para>
+ The
+ <emphasis role="italics">client.jar</emphasis>
+ is meant to contain the WS client application and include a
+ <emphasis role="italics">MANIFEST.MF</emphasis>
+ file specifying the proper
+ <code>Main-Class</code>
+ as well as
+ <link linkend="sid-4784150">JBoss Module
dependencies</link>
+ , for instance:
+ </para>
+ <informalexample>
+ <programlisting>
+Manifest-Version: 1.0
+Main-Class: org.jboss.test.ws.jaxws.jbws1666.TestClient
+Dependencies: org.jboss.ws.cxf.jbossws-cxf-client
+</programlisting>
+ </informalexample>
+ </section>
+ <section id="sid-3735860_QuickStart-Flatclasspathsetup">
+
+ <title>Flat classpath setup</title>
+ <para>
+ Finally, users can of course setup their application classpath manually (e.g
when compiling and running the application directly through
+ <code>javac</code>
+ /
+ <code>java</code>
+ command or using
+ <code>Ant</code>
+ ). The JBossWS testsuite can be used to derive the whole set of files to be
used; the testsuite can be run either using Maven (from the source distribution) or Ant
(from the binary distribution). A verbose execution reveals the list of jar. As for the
Maven project approach mentioned above, properly setting
+ <emphasis role="italics">java.endorsed.dirs</emphasis>
+ system property is also required.
+ </para>
+ </section>
+ </section>
<section id="sid-3735860_QuickStart-Appendix">
<title>Appendix</title>
@@ -356,7 +514,8 @@
<title>Sample wsdl contract</title>
<informalexample>
- <programlisting><definitions
+ <programlisting>
+<definitions
name='ProfileMgmtService'
targetNamespace='http://org.jboss.ws/samples/retail/profile'
xmlns='http://schemas.xmlsoap.org/wsdl/'
@@ -442,7 +601,8 @@
location='http://<HOST>:<PORT>/jaxws-samples-retail/ProfileMgmtBean'/>
</port>
</service>
-</definitions></programlisting>
+</definitions>
+</programlisting>
</informalexample>
</section>
</section>
Modified: stack/cxf/trunk/modules/dist/src/main/doc/chapter-3-JAX_WS_User_Guide.xml
===================================================================
--- stack/cxf/trunk/modules/dist/src/main/doc/chapter-3-JAX_WS_User_Guide.xml 2012-10-12
14:07:42 UTC (rev 16873)
+++ stack/cxf/trunk/modules/dist/src/main/doc/chapter-3-JAX_WS_User_Guide.xml 2012-10-15
08:51:56 UTC (rev 16874)
@@ -412,6 +412,7 @@
<emphasis role="italics">
<ulink
url="http://www.jboss.org/j2ee/dtd/service-ref_5_0.dtd">serv...
</emphasis>
+ .
</para>
</section>
</section>
Modified: stack/cxf/trunk/modules/dist/src/main/doc/chapter-4-JAX_WS_Tools.xml
===================================================================
--- stack/cxf/trunk/modules/dist/src/main/doc/chapter-4-JAX_WS_Tools.xml 2012-10-12
14:07:42 UTC (rev 16873)
+++ stack/cxf/trunk/modules/dist/src/main/doc/chapter-4-JAX_WS_Tools.xml 2012-10-15
08:51:56 UTC (rev 16874)
@@ -293,7 +293,8 @@
{
return arg0;
}
-}</programlisting>
+}
+</programlisting>
</informalexample>
</section>
</section>
@@ -330,7 +331,8 @@
<port binding="tns:EchoBinding" name="EchoPort">
<soap:address
location="http://localhost.localdomain:8080/echo/Echo"/>
</port>
-</service></programlisting>
+</service>
+</programlisting>
</informalexample>
<para>
Using the online deployed version with
@@ -431,7 +433,7 @@
as shown below:
</para>
<informalexample>
- <programlisting>EchoService service = new EchoService();
+ <programlisting> EchoService service = new EchoService();
Echo echo = service.getEchoPort();
/* Set NEW Endpoint Location */
@@ -498,12 +500,13 @@
-w --wsdlLocation=<loc> Value to use for
@WebServiceClient.wsdlLocation
-o, --output=<directory> The directory to put generated artifacts
-s, --source=<directory> The directory to put Java source
- -t, --target=<2.0|2.1|2.2> The JAX-WS specification target
+ -t, --target=<2.1|2.2> The JAX-WS specification target
-q, --quiet Be somewhat more quiet
-v, --verbose Show full exception stack traces
-l, --load-consumer Load the consumer and exit (debug utility)
-e, --extension Enable SOAP 1.2 binding extension
- -a, --additionalHeaders Enables processing of implicit SOAP
headers</programlisting>
+ -a, --additionalHeaders Enables processing of implicit SOAP headers
+ -n, --nocompile Do not compile generated sources</programlisting>
</informalexample>
<para>
@@ -764,7 +767,8 @@
</para>
<para>The following example makes the plugin consume the test.wsdl file
and generate SEI and wrappers' java sources. The generated sources are then compiled
together with the other project classes.</para>
<informalexample>
- <programlisting><build>
+ <programlisting>
+<build>
<plugins>
<plugin>
<groupId>org.jboss.ws.plugins</groupId>
@@ -784,11 +788,13 @@
</executions>
</plugin>
</plugins>
-</build></programlisting>
+</build>
+</programlisting>
</informalexample>
<para>You can also specify multiple wsdl files, as well as force the
target package, enable SOAP 1.2 binding and turn the tool's verbose mode
on:</para>
<informalexample>
- <programlisting><build>
+ <programlisting>
+<build>
<plugins>
<plugin>
<groupId>org.jboss.ws.plugins</groupId>
@@ -812,7 +818,8 @@
</executions>
</plugin>
</plugins>
-</build></programlisting>
+</build>
+</programlisting>
</informalexample>
<para>
Finally, if the wsconsume invocation is required for consuming a wsdl to be
used in your testsuite only, you might want to use the
@@ -820,7 +827,8 @@
goal as follows:
</para>
<informalexample>
- <programlisting><build>
+ <programlisting>
+<build>
<plugins>
<plugin>
<groupId>org.jboss.ws.plugins</groupId>
@@ -840,7 +848,8 @@
</executions>
</plugin>
</plugins>
-</build></programlisting>
+</build>
+</programlisting>
</informalexample>
<para>
Plugin stack dependencyThe plugin itself does not have an explicit dependency
to a JBossWS stack, as it's meant for being used with implementations of any supported
version of the
@@ -1099,7 +1108,8 @@
<title>Examples</title>
<para>Generate JAX-WS source and classes in a separate JVM with separate
directories, a custom wsdl location attribute, and a list of binding files from
foo.wsdl:</para>
<informalexample>
- <programlisting><wsconsume
+ <programlisting>
+<wsconsume
fork="true"
verbose="true"
destdir="output"
@@ -1108,7 +1118,8 @@
wsdllocation="handEdited.wsdl"
wsdl="foo.wsdl">
<binding dir="binding-files" includes="*.xml"
excludes="bad.xml"/>
-</wsconsume></programlisting>
+</wsconsume>
+</programlisting>
</informalexample>
</section>
</section>
@@ -1130,7 +1141,8 @@
-h, --help Show this help message
-k, --keep Keep/Generate Java source
-w, --wsdl Enable WSDL file generation
- -c. --classpath=<path< The classpath that contains the endpoint
+ -a, --address The generated port soap:address in wsdl
+ -c. --classpath=<path> The classpath that contains the endpoint
-o, --output=<directory> The directory to put generated artifacts
-r, --resource=<directory> The directory to put resource artifacts
-s, --source=<directory> The directory to put Java source
@@ -1265,7 +1277,10 @@
<para>Whether or not to generate WSDL.</para>
</entry>
<entry>
- <para>false</para>
+ <para>
+ false
+
+ </para>
</entry>
</row>
<row>
@@ -1489,6 +1504,23 @@
</row>
<row>
<entry>
+ <para>
+ address
+
+ </para>
+ </entry>
+ <entry>
+ <para>
+ The generated port soap:address in wsdl.
+
+ </para>
+ </entry>
+ <entry>
+ <para> </para>
+ </entry>
+ </row>
+ <row>
+ <entry>
<para>verbose</para>
</entry>
<entry>
Modified: stack/cxf/trunk/modules/dist/src/main/doc/chapter-5-Advanced_User_Guide.xml
===================================================================
--- stack/cxf/trunk/modules/dist/src/main/doc/chapter-5-Advanced_User_Guide.xml 2012-10-12
14:07:42 UTC (rev 16873)
+++ stack/cxf/trunk/modules/dist/src/main/doc/chapter-5-Advanced_User_Guide.xml 2012-10-15
08:51:56 UTC (rev 16874)
@@ -3,28 +3,83 @@
<chapter id="sid-3866738">
<title>Advanced User Guide</title>
+ <section id="sid-3866738_AdvancedUserGuide-Logging">
+
+ <title>Logging</title>
+ <para>Logging of inbound and outbound messages is a common need. Different
approaches are available for achieving that:</para>
+ <section id="sid-3866738_AdvancedUserGuide-JAXWSHandlerapproach">
+
+ <title>JAX-WS Handler approach</title>
+ <para>
+ A portable way of performing logging is writing a simple JAX-WS handler dumping
the messages that are passed in it; the handler can be added to the desired
client/endpoints (programmatically / using
+ <code>@HandlerChain</code>
+ JAX-WS annotation).
+ </para>
+ <para>
+ The
+ <link linkend="sid-41713670">predefined client and endpoint
configuration</link>
+ mechanism allows user to add the logging handler to any client/endpoint or to
some of them only (in which case the
+ <code>@EndpointConfig</code>
+ annotation / JBossWS API is required though).
+ </para>
+ </section>
+ <section id="sid-3866738_AdvancedUserGuide-ApacheCXFapproach">
+
+ <title>Apache CXF approach</title>
+ <para>Apache CXF also comes with logging interceptors that can be easily
used to log messages to the console or configured client/server log files. Those
interceptors can be added to client, endpoint and buses in multiple ways:</para>
+ <section id="sid-3866738_AdvancedUserGuide-Systemproperty">
+
+ <title>System property</title>
+ <para>
+ Setting the
+ <code>org.apache.cxf.logging.enabled</code>
+ system property to true causes the logging interceptors to be added to any
+ <code>Bus</code>
+ instance being created on the JVM.
+ </para>
+ <important>
+ <para>On JBoss AS 7, the system property is easily set by adding what
follows to the standalone / domain server configuration just after the extensions
section:</para>
+ <informalexample>
+ <programlisting><system-properties>
+ <property name="org.apache.cxf.logging.enabled"
value="true"/>
+</system-properties></programlisting>
+ </informalexample>
+ </important>
+ </section>
+ <section
id="sid-3866738_AdvancedUserGuide-Manualinterceptoradditionandloggingfeature">
+
+ <title>Manual interceptor addition and logging feature</title>
+ <para>
+ Logging interceptors can be selectively added to endpoints using the Apache
CXF annotations
+ <code>(a)org.apache.cxf.interceptor.InInterceptors</code>
+ and
+ <code>(a)org.apache.cxf.interceptor.OutInterceptors</code>
+ . The same is achieved on client side by programmatically adding new
instances of the logging interceptors to the client or the bus.
+ </para>
+ <para>
+ Alternatively, Apache CXF also comes with a
+ <code>org.apache.cxf.feature.LoggingFeature</code>
+ that can be used on clients and endpoints (either annotating them with
+ <code>(a)org.apache.cxf.feature.Features</code>
+ or directly with
+ <code>(a)org.apache.cxf.annotations.Logging</code>
+ ).
+ </para>
+ <para>Finally, the interceptors and feature can also be configured using
Spring descriptors when Spring is available for the JBossWS-CXF integration on the
application server.</para>
+ <para>
+ Please refer to the
+ <ulink
url="http://cxf.apache.org/docs/debugging-and-logging.html#Debugging...
CXF documentation</ulink>
+ for more details.
+ </para>
+ </section>
+ </section>
+ </section>
<section id="sid-3866738_AdvancedUserGuide-WS%5Csupport">
<title>WS-* support</title>
<para>JBossWS includes most of the WS-* specification functionalities through
the integration with Apache CXF. In particular, the whole WS-Security Policy framework is
fully supported, enabling full contract driven configuration of complex features like
WS-Security.</para>
<para>In details information available further down in this documentation
book.</para>
</section>
- <section id="sid-3866738_AdvancedUserGuide-JAXBIntroductions">
-
- <title>JAXB Introductions</title>
- <para>
- As Kohsuke Kawaguchi wrote on
- <ulink
url="http://weblogs.java.net/blog/kohsuke/archive/2007/07/binding_3r...
blog</ulink>
- , one common complaint from the JAXB users is the lack of support for binding 3rd
party classes. The scenario is this: you are trying to annotate your classes with JAXB
annotations to make it XML bindable, but some of the classes are coming from libraries and
JDK, and thus you cannot put necessary JAXB annotations on it.
- </para>
- <para>To solve this JAXB has been designed to provide hooks for programmatic
introduction of annotations to the runtime.</para>
- <para>This is currently leveraged by the JBoss JAXB Introductions project,
using which users can define annotations in XML and make JAXB see those as if those were
in the class files (perhaps coming from 3rd party libraries).</para>
- <para>
- Take a look at the
- <ulink
url="http://community.jboss.org/docs/DOC-10075">JAXB
Introductions page</ulink>
- on the wiki and at the examples in the sources.
- </para>
- </section>
<section id="sid-3866738_AdvancedUserGuide-Addressrewrite">
<title>Address rewrite</title>
@@ -36,9 +91,14 @@
<section
id="sid-3866738_AdvancedUserGuide-Serverconfigurationoptions">
<title>Server configuration options</title>
- <para>The configuration options are part of the webservices subsystem
section of the JBoss Application Server 7 domain model.</para>
+ <para>
+ The configuration options are part of the
+ <ulink
url="https://docs.jboss.org/author/display/AS71/Web+services+configu...
subsystem section</ulink>
+ of the JBoss Application Server 7 domain model.
+ </para>
<informalexample>
- <programlisting><subsystem
xmlns="urn:jboss:domain:webservices:1.1"
xmlns:javaee="http://java.sun.com/xml/ns/javaee"
+ <programlisting>
+<subsystem xmlns="urn:jboss:domain:webservices:1.1"
xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xmlns:jaxwsconfig="urn:jboss:jbossws-jaxws-config:4.0">
<wsdl-host>localhost</wsdl-host>
<modify-wsdl-address>true</modify-wsdl-address>
@@ -46,7 +106,8 @@
<wsdl-port>8080</wsdl-port>
<wsdl-secure-port>8443</wsdl-secure-port>
-->
-</subsystem></programlisting>
+</subsystem>
+</programlisting>
</informalexample>
<para>
If the content of
@@ -78,6 +139,483 @@
<para>Of course, when a confidential transport address is required, the
addresses are always rewritten using https protocol and the port currently configured for
the https/ssl connector.</para>
</section>
</section>
+ <section
id="sid-3866738_AdvancedUserGuide-Configurationthroughdeploymentdescriptor">
+
+ <title>Configuration through deployment descriptor</title>
+ <para>
+ The
+ <code>jboss-webservices.xml</code>
+ deployment descriptor can be used to provide additional configuration for a given
deployment. The expected location of it is:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ <code>META-INF/jboss-webservices.xml</code>
+ for EJB webservice deployments
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <code>WEB-INF/jboss-webservices.xml</code>
+ for POJO webservice deployments and EJB webservice endpoints bundled in
+ <code>war</code>
+ archives
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ The structure of file is the following (schemas are available
+ <ulink
url="http://anonsvn.jboss.org/repos/jbossws/spi/trunk/src/main/resou...
+ ):
+ </para>
+ <informalexample>
+ <programlisting>
+<webservices>
+ <context-root/>?
+ <config-name/>?
+ <config-file/>?
+ <property>*
+ <name/>
+ <value/>
+ </property>
+ <port-component>*
+ <ejb-name/>
+ <port-component-name/>
+ <port-component-uri/>?
+ <auth-method/>?
+ <transport-guarantee/>?
+ <secure-wsdl-access/>?
+ </port-component>
+ <webservice-description>*
+ <webservice-description-name/>
+ <wsdl-publish-location/>?
+ </webservice-description>
+</webservices>
+</programlisting>
+ </informalexample>
+ <section id="sid-3866738_AdvancedUserGuide-contextrootelement">
+
+ <title>context-root element</title>
+ <para>
+ Element
+ <code><context-root></code>
+ can be used to customize context root of webservices deployment.
+ </para>
+ <informalexample>
+ <programlisting>
+<webservices>
+ <context-root>foo</context-root>
+</webservices>
+</programlisting>
+ </informalexample>
+ </section>
+ <section
id="sid-3866738_AdvancedUserGuide-confignameandconfigfileelements">
+
+ <title>config-name and config-file elements</title>
+ <para>
+ Elements
+ <code><config-name></code>
+ and
+ <code><config-file></code>
+ can be used to associate any endpoint provided in the deployment with a given
+ <link linkend="sid-41713670">endpoint
configuration</link>
+ . Endpoint configuration are either specified in the referenced config file or
in the JBoss AS 7 domain model (webservices subsystem). For further details on the
endpoint configurations and their management in the domain model, please see the related
+ <ulink
url="https://docs.jboss.org/author/display/AS71/Web+services+configu...
+ .
+ </para>
+ <informalexample>
+ <programlisting>
+<webservices>
+ <config-name>Standard WSSecurity Endpoint</config-name>
+ <config-file>META-INF/custom.xml</config-file>
+</webservices>
+</programlisting>
+ </informalexample>
+ </section>
+ <section id="sid-3866738_AdvancedUserGuide-propertyelement">
+
+ <title>property element</title>
+ <para>
+ <code><property></code>
+ elements can be used to setup simple property values to configure the ws stack
behavior. Allowed property names and values are mentioned in the guide under related
topics.
+ </para>
+ <informalexample>
+ <programlisting>
+<property>
+ <name>prop.name</name>
+ <value>prop.value</value>
+</property>
+</programlisting>
+ </informalexample>
+ </section>
+ <section id="sid-3866738_AdvancedUserGuide-portcomponentelement">
+
+ <title>component element</title>
+ <para>
+ Element
+ <code><port-component></code>
+ can be used to customize EJB endpoint target URI or to configure security
related properties.
+ </para>
+ <informalexample>
+ <programlisting>
+<webservices>
+ <port-component>
+ <ejb-name>TestService</ejb-name>
+
<port-component-name>TestServicePort</port-component-name>
+ <port-component-uri>/*</port-component-uri>
+ <auth-method>BASIC</auth-method>
+ <transport-guarantee>NONE</transport-guarantee>
+ <secure-wsdl-access>true</secure-wsdl-access>
+ </port-component>
+</webservices>
+</programlisting>
+ </informalexample>
+ </section>
+ <section
id="sid-3866738_AdvancedUserGuide-webservicedescriptionelement">
+
+ <title>webservice-description element</title>
+ <para>
+ Element
+ <code><webservice-description></code>
+ can be used to customize (override) webservice WSDL publish location.
+ </para>
+ <informalexample>
+ <programlisting>
+<webservices>
+ <webservice-description>
+
<webservice-description-name>TestService</webservice-description-name>
+
<wsdl-publish-location>file:///bar/foo.wsdl</wsdl-publish-location>
+ </webservice-description>
+</webservices>
+</programlisting>
+ </informalexample>
+ </section>
+ </section>
+ <section
id="sid-3866738_AdvancedUserGuide-SchemavalidationofSOAPmessages">
+
+ <title>Schema validation of SOAP messages</title>
+ <para>Apache CXF has a feature for validating incoming and outgoing SOAP
messages on both client and server side. The validation is performed against the relevant
schema in the endpoint wsdl contract (server side) or the wsdl contract used for building
up the service proxy (client side).</para>
+ <para>Schema validation can be turned on programmatically on client
side</para>
+ <informalexample>
+
<programlisting>((BindingProvider)proxy).getRequestContext().put("schema-validation-enabled",
true);</programlisting>
+ </informalexample>
+ <para>
+ or using the
+ <code>(a)org.apache.cxf.annotations.SchemaValidation</code>
+ annotation on server side
+ </para>
+ <informalexample>
+ <programlisting>import javax.jws.WebService;
+import org.apache.cxf.annotations.SchemaValidation;
+
+@WebService(...)
+@SchemaValidation
+public class ValidatingHelloImpl implements Hello {
+ ...
+}</programlisting>
+ </informalexample>
+ <para>
+ Alternatively, any endpoint and client running in-container can be associated to
a JBossWS
+ <link linkend="sid-41713670">predefined
configuration</link>
+ having the
+ <code>schema-validation-enabled</code>
+ property set to
+ <code>true</code>
+ in the referenced config file.
+ </para>
+ <para>
+ Finally, JBossWS also allows for server-wide (default) setup of schema validation
by using the
+ <emphasis
role="italics">Standard-Endpoint-Config</emphasis>
+ and
+ <emphasis role="italics">Standard-Client-Config</emphasis>
+ special configurations (which apply to any client / endpoint unless a different
configuration is specified for them)
+ </para>
+ <informalexample>
+ <programlisting><subsystem
xmlns="urn:jboss:domain:webservices:1.2">
+ ...
+ <endpoint-config name="Standard-Endpoint-Config">
+ <property name="schema-validation-enabled"
value="true"/>
+ </endpoint-config>
+ ...
+ <client-config name="Standard-Client-Config">
+ <property name="schema-validation-enabled"
value="true"/>
+ </client-config>
+</subsystem></programlisting>
+ </informalexample>
+ </section>
+ <section id="sid-3866738_AdvancedUserGuide-JAXBIntroductions">
+
+ <title>JAXB Introductions</title>
+ <para>
+ As Kohsuke Kawaguchi wrote on
+ <ulink
url="http://weblogs.java.net/blog/kohsuke/archive/2007/07/binding_3r...
blog</ulink>
+ , one common complaint from the JAXB users is the lack of support for binding 3rd
party classes. The scenario is this: you are trying to annotate your classes with JAXB
annotations to make it XML bindable, but some of the classes are coming from libraries and
JDK, and thus you cannot put necessary JAXB annotations on it.
+ </para>
+ <para>To solve this JAXB has been designed to provide hooks for programmatic
introduction of annotations to the runtime.</para>
+ <para>This is currently leveraged by the JBoss JAXB Introductions project,
using which users can define annotations in XML and make JAXB see those as if those were
in the class files (perhaps coming from 3rd party libraries).</para>
+ <para>
+ Take a look at the
+ <ulink
url="http://community.jboss.org/docs/DOC-10075">JAXB
Introductions page</ulink>
+ on the wiki and at the examples in the sources.
+ </para>
+ </section>
+ <section id="sid-41713670">
+
+ <title>Predefined client and endpoint configurations</title>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Overview">
+
+ <title>Overview</title>
+ <para>
+ JBossWS comes with a concept of
+ <emphasis role="italics">predefined
configurations</emphasis>
+ , which are kind of basic templates that can be used for both JAX-WS client and
JAX-WS endpoint setup. Configurations can include JAX-WS handlers as well as basic
key/value properties declarations.
+ </para>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Handlers">
+
+ <title>Handlers</title>
+ <para>For each endpoint configuration, both PRE and POST handler chains
can be specified. Each handler chain may include JAXWS handlers. For outbound messages,
PRE handler chain handlers are meant to be executed before any handler attached to the
endpoints using standard JAXWS means (e.g. using @HandlerChain), while POST handler chain
handlers are executed after usual endpoint handlers. For inbound messages, the opposite
applies.</para>
+ <informalexample>
+ <programlisting>* Server inbound messages
+Client --> ... --> POST HANDLER --> ENDPOINT HANDLERS --> PRE
HANDLERS --> Endpoint
+
+* Server outbound messages
+Endpoint --> PRE HANDLER --> ENDPOINT HANDLERS --> POST HANDLERS
--> ... --> Client</programlisting>
+ </informalexample>
+ <para>The same applies for client configurations.</para>
+ </section>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Properties">
+
+ <title>Properties</title>
+ <para>Key/value properties are used for controlling both some Apache CXF
internals and some JBossWS options. Specific supported values are mentioned where relevant
in the rest of the documentation.</para>
+ </section>
+ </section>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Assigningconfigurations">
+
+ <title>Assigning configurations</title>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Endpointconfigurationassignment">
+
+ <title>Endpoint configuration assignment</title>
+ <para>
+ JAX-WS endpoints can be assigned to a given configuration by annotating them
with the
+ <code>org.jboss.ws.api.annotation.EndpointConfig</code>
+ annotation:
+ </para>
+ <informalexample>
+ <programlisting>@EndpointConfig(configFile =
"WEB-INF/jaxws-endpoint-config.xml", configName = "Custom WS-Security
Endpoint")
+public class ServiceImpl implements ServiceIface
+{
+ public String sayHello()
+ {
+ return "Secure Hello World!";
+ }
+}</programlisting>
+ </informalexample>
+ <para>
+ The
+ <code>configFile</code>
+ attribute is used to specify with config file, if any, is to be used to load
the configuration; if
+ <code>configFile</code>
+ is not set, the application server configurations are used.
+ </para>
+ <para>
+ The
+ <code>configName</code>
+ attributed is used to specify the name of the configuration to be used.
+ </para>
+ <para>
+ Alternatively, configurations can be assigned to endpoints through the
+ <link linkend="sid-3866738">jboss-webservices.xml deployment
descriptor</link>
+ .
+ </para>
+ <para>
+ The configuration file, if any, needs to be included in the endpoint
deployment; the
+ <ulink
url="http://anonsvn.jboss.org/repos/jbossws/spi/tags/jbossws-spi-2.1...
schema</ulink>
+ defines its contents and is included in the
+ <emphasis role="italics">jbossws-spi</emphasis>
+ artifact.
+ </para>
+ </section>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Clientconfigurationassignment">
+
+ <title>Client configuration assignment</title>
+ <para>JBossWS API comes with facility classes for assigning
configurations when building up a client; JAXWS handlers can be read from client
configurations as follows:</para>
+ <informalexample>
+ <programlisting>import
org.jboss.ws.api.configuration.ClientConfigUtil;
+import org.jboss.ws.api.configuration.ClientConfigurer;
+
+...
+
+Service service = Service.create(wsdlURL, serviceName);
+Endpoint port = (Endpoint)service.getPort(Endpoint.class);
+BindingProvider bp = (BindingProvider)port;
+ClientConfigUtil.setConfigHandlers(bp, "META-INF/jaxws-client-config.xml",
"Custom Client Config 1");
+port.echo("Kermit");
+
+...
+
+ClientConfigurer configurer = ClientConfigUtil.resolveClientConfigurer();
+configurer.setConfigHandlers(bp, "META-INF/jaxws-client-config.xml",
"Custom Client Config 2");
+port.echo("Kermit");
+
+...
+
+configurer.setConfigHandlers(bp, "META-INF/jaxws-client-config.xml",
"Custom Client Config 3");
+port.echo("Kermit");
+
+
+...
+
+configurer.setConfigHandlers(bp, null, "Container Custom Client Config");
//reads from container configurations
+port.echo("Kermit");
+</programlisting>
+ </informalexample>
+ <para>... similarly, properties are read from client configurations as
follows:</para>
+ <informalexample>
+ <programlisting>import
org.jboss.ws.api.configuration.ClientConfigUtil;
+import org.jboss.ws.api.configuration.ClientConfigurer;
+
+...
+
+Service service = Service.create(wsdlURL, serviceName);
+Endpoint port = (Endpoint)service.getPort(Endpoint.class);
+
+ClientConfigUtil.setConfigProperties(port, "META-INF/jaxws-client-config.xml",
"Custom Client Config 1");
+port.echo("Kermit");
+
+...
+
+ClientConfigurer configurer = ClientConfigUtil.resolveClientConfigurer();
+configurer.setConfigProperties(port, "META-INF/jaxws-client-config.xml",
"Custom Client Config 2");
+port.echo("Kermit");
+
+...
+
+configurer.setConfigProperties(port, "META-INF/jaxws-client-config.xml",
"Custom Client Config 3");
+port.echo("Kermit");
+
+
+...
+
+configurer.setConfigProperties(port, null, "Container Custom Client Config");
//reads from container configurations
+port.echo("Kermit");
+</programlisting>
+ </informalexample>
+ <para>
+ The default
+ <code>ClientConfigurer</code>
+ implementation parses the specified configuration file, if any, after having
resolved it as a resources using the current thread context classloader. The
+ <ulink
url="http://anonsvn.jboss.org/repos/jbossws/spi/tags/jbossws-spi-2.1...
schema</ulink>
+ defines the descriptor contents and is included in the
+ <emphasis role="italics">jbossws-spi</emphasis>
+ artifact.
+ </para>
+ </section>
+ </section>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Applicationserverconfigurations">
+
+ <title>Application server configurations</title>
+ <para>
+ JBoss Application Server 7.x allows declaring JBossWS client and server
predefined configurations in the
+ <emphasis role="italics">webservices</emphasis>
+ subsystem section of the server model. As a consequence it is possible to
declare server-wide handlers to be added to the chain of each endpoint or client assigned
to a given configuration.
+ </para>
+ <para>
+ Please refer to the
+ <ulink
url="https://docs.jboss.org/author/display/AS71/Web+services+configu...
Application Server 7 documentation</ulink>
+ for any detail on managing the
+ <emphasis role="italics">webservices</emphasis>
+ subsystem to add, remove or modify handlers and properties.
+ </para>
+ <para>
+ The allowed contents in the
+ <emphasis role="italics">webservices</emphasis>
+ subsystem are defined by the
+ <ulink
url="https://github.com/jbossas/jboss-as/blob/master/build/src/main/...
+ included in the application server.
+ </para>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Standardconfigurations">
+
+ <title>Standard configurations</title>
+ <para>
+ Clients running in-container as well as endpoints are assigned standard
configurations by default. Those are used unless different configurations are set as
previously described. This way administrators can tune default handler chains for client
and endpoints developers did not assign a specific configuration to. The name for such
default configuration, to be used in the JBoss AS 7 webservices subsystem are
+ <code>Standard-Client-Config</code>
+ and
+ <code>Standard-Endpoint-Config</code>
+ .
+ </para>
+ </section>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Handlersclassloading">
+
+ <title>Handlers classloading</title>
+ <para>
+ When setting a server-wide handler, please note the handler class needs to be
available either through each ws deployment classloader or the
+ <code>org.jboss.as.webservices.server.integration:main</code>
+ module classloader. As a consequence proper module dependencies might need to
be specified either in the deployments that are going to leverage a given predefined
configuration or directly in the previously mentioned AS7 module.
+ </para>
+ </section>
+ </section>
+ <section
id="sid-41713670_Predefinedclientandendpointconfigurations-Examples">
+
+ <title>Examples</title>
+ <example>
+ <title>JBoss AS 7.2 default configurations</title>
+ <programlisting>
+<subsystem xmlns="urn:jboss:domain:webservices:1.2">
+ <!-- ... -->
+ <endpoint-config name="Standard-Endpoint-Config"/>
+ <endpoint-config name="Recording-Endpoint-Config">
+ <pre-handler-chain name="recording-handlers"
protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP
##SOAP12_HTTP_MTOM">
+ <handler name="RecordingHandler"
class="org.jboss.ws.common.invocation.RecordingServerHandler"/>
+ </pre-handler-chain>
+ </endpoint-config>
+ <client-config name="Standard-Client-Config"/>
+</subsystem></programlisting>
+ </example>
+ <example>
+ <title>A configuration file for a deployment specific ws-security
endpoint setup</title>
+ <programlisting>
+<jaxws-config xmlns="urn:jboss:jbossws-jaxws-config:4.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xmlns:javaee="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="urn:jboss:jbossws-jaxws-config:4.0
schema/jbossws-jaxws-config_4_0.xsd">
+ <endpoint-config>
+ <config-name>Custom WS-Security Endpoint</config-name>
+ <property>
+
<property-name>ws-security.signature.properties</property-name>
+ <property-value>bob.properties</property-value>
+ </property>
+ <property>
+
<property-name>ws-security.encryption.properties</property-name>
+ <property-value>bob.properties</property-value>
+ </property>
+ <property>
+
<property-name>ws-security.signature.username</property-name>
+ <property-value>bob</property-value>
+ </property>
+ <property>
+
<property-name>ws-security.encryption.username</property-name>
+ <property-value>alice</property-value>
+ </property>
+ <property>
+
<property-name>ws-security.callback-handler</property-name>
+
<property-value>org.jboss.test.ws.jaxws.samples.wsse.policy.basic.KeystorePasswordCallback</property-value>
+ </property>
+ </endpoint-config>
+</jaxws-config></programlisting>
+ </example>
+ <example>
+ <title>JBoss AS 7.2 default configurations modified to default to SOAP
messages schema-validation on</title>
+ <programlisting><subsystem
xmlns="urn:jboss:domain:webservices:1.2">
+ <!-- ... -->
+ <endpoint-config name="Standard-Endpoint-Config">
+ <property name="schema-validation-enabled"
value="true"/>
+ </endpoint-config>
+ <!-- ... -->
+ <client-config name="Standard-Client-Config">
+ <property name="schema-validation-enabled"
value="true"/>
+ </client-config>
+</subsystem></programlisting>
+ </example>
+ </section>
+ </section>
<section id="sid-3866749">
<title>Authentication</title>
@@ -126,9 +664,11 @@
</informalexample>
<para>or modifying the jboss-web.xml for POJO endpoints</para>
<informalexample>
- <programlisting><jboss-web>
+ <programlisting>
+<jboss-web>
<security-domain>JBossWS</security-domain>
-</jboss-web></programlisting>
+</jboss-web>
+</programlisting>
</informalexample>
<para>The security domain as well as its the authentication and
authorization mechanisms are defined differently depending on the JBoss Application Server
in use.</para>
</section>
@@ -185,160 +725,170 @@
<section id="sid-3866786">
<title>Apache CXF integration</title>
- <para>
- All JAX-WS functionalities provided by JBossWS on top of JBoss Application Server
are currently served through a proper integration of the JBoss Web Services stack with
most of the
- <ulink
url="http://cxf.apache.org/">Apache CXF</ulink>
- project modules.
- </para>
- <para>Apache CXF is an open source services framework. It allows building and
developing services using frontend programming APIs (including JAX-WS), with services
speaking a variety of protocols such as SOAP and XML/HTTP over a variety of transports
such as HTTP and JMS.</para>
- <para>
- The integration layer (
- <emphasis role="italics">JBossWS-CXF</emphasis>
- in short hereafter) is mainly meant for:
- </para>
- <itemizedlist>
- <listitem>
- <para>allowing using standard webservices APIs (including JAX-WS) on
JBoss Application Server; this is performed internally leveraging Apache CXF without
requiring the user to deal with it;</para>
- </listitem>
- <listitem>
- <para>allowing using Apache CXF advanced features (including WS-*) on
top of JBoss Application server without requiring the user to deal with / setup / care
about the required integration steps for running in such a container.</para>
- </listitem>
- </itemizedlist>
- <para>In order for achieving the goals above, the JBossWS-CXF integration
supports the JBoss endpoint deployment and comes with many internal customizations on top
of Apache CXF.</para>
- <para>
- In the next sections a list of technical suggestions and notes on the integration
is provided; please also refer to the
- <ulink
url="http://cxf.apache.org/docs/index.html">Apache CXF
official documentation</ulink>
- for in-dept details on the CXF architecture.
- </para>
- <section
id="sid-3866786_ApacheCXFintegration-CreatingaBusinstance">
+ <section
id="sid-3866786_ApacheCXFintegration-JBossWSintegrationlayerwithApacheCXF">
- <title>Creating a Bus instance</title>
+ <title>JBossWS integration layer with Apache CXF</title>
<para>
- Most of the Apache CXF features are configurable using the
- <code>org.apache.cxf.Bus</code>
- class. While for basic JAX-WS usage the user might never need to explicitly
deal with Bus, using Apache CXF specific features generally requires getting a handle to
a
- <code>org.apache.cxf.Bus</code>
- instance. This can happen on client side as well as in a ws endpoint or handler
business code.
+ All JAX-WS functionalities provided by JBossWS on top of JBoss Application
Server are currently served through a proper integration of the JBoss Web Services stack
with most of the
+ <ulink
url="http://cxf.apache.org/">Apache CXF</ulink>
+ project modules.
</para>
+ <para>Apache CXF is an open source services framework. It allows building
and developing services using frontend programming APIs (including JAX-WS), with services
speaking a variety of protocols such as SOAP and XML/HTTP over a variety of transports
such as HTTP and JMS.</para>
<para>
- New Bus instances are produced by the currently configured
- <code>org.apache.cxf.BusFactory</code>
- implementation the following way:
+ The integration layer (
+ <emphasis role="italics">JBossWS-CXF</emphasis>
+ in short hereafter) is mainly meant for:
</para>
- <informalexample>
- <programlisting>Bus bus =
BusFactory.newInstance().createBus();</programlisting>
- </informalexample>
+ <itemizedlist>
+ <listitem>
+ <para>allowing using standard webservices APIs (including JAX-WS) on
JBoss Application Server; this is performed internally leveraging Apache CXF without
requiring the user to deal with it;</para>
+ </listitem>
+ <listitem>
+ <para>allowing using Apache CXF advanced features (including WS-*) on
top of JBoss Application server without requiring the user to deal with / setup / care
about the required integration steps for running in such a container.</para>
+ </listitem>
+ </itemizedlist>
+ <para>In order for achieving the goals above, the JBossWS-CXF integration
supports the JBoss endpoint deployment and comes with many internal customizations on top
of Apache CXF.</para>
<para>
- The algorithm for selecting the actual implementation of
- <code>BusFactory</code>
- to be used leverages the Service API, basically looking for optional
configurations in
- <emphasis
role="italics">META-INF/services/...</emphasis>
- location using the current thread context classloader. JBossWS-CXF integration
comes with his own implementation of
- <code>BusFactory</code>
- ,
-
<code>org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory</code>
- , that allows for automatic detection of
- <emphasis role="italics">Spring</emphasis>
- availability as well as seamless setup of JBossWS customizations on top of
Apache CXF. So, assuming the JBossWS-CXF libraries are available in the current thread
context classloader, the
- <code>JBossWSBusFactory</code>
- is
- <emphasis role="italics">automatically</emphasis>
- retrieved by the
- <code>BusFactory.newInstance()</code>
- call above.
+ In the next sections a list of technical suggestions and notes on the
integration is provided; please also refer to the
+ <ulink
url="http://cxf.apache.org/docs/index.html">Apache CXF
official documentation</ulink>
+ for in-depth details on the CXF architecture.
</para>
- <para>
- JBossWS users willing to explicitely use functionalities of
- <code>org.apache.cxf.bus.spring.SpringBusFactory</code>
- or
- <code>org.apache.cxf.bus.CXFBusFactory</code>
- <emphasis role="italics">,</emphasis>
- get the same API with JBossWS additions through
- <code>JBossWSBusFactory</code>
- :
- </para>
- <informalexample>
- <programlisting>String myConfigFile = ...
+ </section>
+ <section id="sid-3866786_ApacheCXFintegration-Bususage">
+
+ <title>Bus usage</title>
+ <section
id="sid-3866786_ApacheCXFintegration-CreatingaBusinstance">
+
+ <title>Creating a Bus instance</title>
+ <para>
+ Most of the Apache CXF features are configurable using the
+ <code>org.apache.cxf.Bus</code>
+ class. While for basic JAX-WS usage the user might never need to explicitly
deal with Bus, using Apache CXF specific features generally requires getting a handle to
a
+ <code>org.apache.cxf.Bus</code>
+ instance. This can happen on client side as well as in a ws endpoint or
handler business code.
+ </para>
+ <para>
+ New Bus instances are produced by the currently configured
+ <code>org.apache.cxf.BusFactory</code>
+ implementation the following way:
+ </para>
+ <informalexample>
+ <programlisting>Bus bus =
BusFactory.newInstance().createBus();</programlisting>
+ </informalexample>
+ <para>
+ The algorithm for selecting the actual implementation of
+ <code>BusFactory</code>
+ to be used leverages the Service API, basically looking for optional
configurations in
+ <emphasis
role="italics">META-INF/services/...</emphasis>
+ location using the current thread context classloader. JBossWS-CXF
integration comes with his own implementation of
+ <code>BusFactory</code>
+ ,
+
<code>org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory</code>
+ , that allows for automatic detection of
+ <emphasis role="italics">Spring</emphasis>
+ availability as well as seamless setup of JBossWS customizations on top of
Apache CXF. So, assuming the JBossWS-CXF libraries are available in the current thread
context classloader, the
+ <code>JBossWSBusFactory</code>
+ is
+ <emphasis role="italics">automatically</emphasis>
+ retrieved by the
+ <code>BusFactory.newInstance()</code>
+ call above.
+ </para>
+ <para>
+ JBossWS users willing to explicitely use functionalities of
+ <code>org.apache.cxf.bus.spring.SpringBusFactory</code>
+ or
+ <code>org.apache.cxf.bus.CXFBusFactory</code>
+ <emphasis role="italics">,</emphasis>
+ get the same API with JBossWS additions through
+ <code>JBossWSBusFactory</code>
+ :
+ </para>
+ <informalexample>
+ <programlisting>String myConfigFile = ...
Bus bus = new JBossWSBusFactory().createBus(myConfigFile);</programlisting>
- </informalexample>
- <informalexample>
- <programlisting>Map<Class, Object> myExtensions = new
HashMap<Class, Object>();
+ </informalexample>
+ <informalexample>
+ <programlisting>Map<Class, Object> myExtensions = new
HashMap<Class, Object>();
myExtensions.put(...);
Bus bus = new JBossWSBusFactory().createBus(myExtensions);</programlisting>
- </informalexample>
- </section>
- <section
id="sid-3866786_ApacheCXFintegration-UsingexistingBusinstances">
-
- <title>Using existing Bus instances</title>
- <para>
- Apache CXF keeps reference to a global default
- <code>Bus</code>
- instance as well as to a thread default bus for each thread. That is performed
through static members in
- <code>org.apache.cxf.BusFactory</code>
- <emphasis role="italics">,</emphasis>
- which also comes with the following methods in the public API:
- </para>
- <informalexample>
- <programlisting>public static synchronized Bus getDefaultBus()
+ </informalexample>
+ </section>
+ <section
id="sid-3866786_ApacheCXFintegration-UsingexistingBusinstances">
+
+ <title>Using existing Bus instances</title>
+ <para>
+ Apache CXF keeps reference to a global default
+ <code>Bus</code>
+ instance as well as to a thread default bus for each thread. That is
performed through static members in
+ <code>org.apache.cxf.BusFactory</code>
+ <emphasis role="italics">,</emphasis>
+ which also comes with the following methods in the public API:
+ </para>
+ <informalexample>
+ <programlisting>
+public static synchronized Bus getDefaultBus()
public static synchronized Bus getDefaultBus(boolean createIfNeeded)
public static synchronized void setDefaultBus(Bus bus)
public static Bus getThreadDefaultBus()
public static Bus getThreadDefaultBus(boolean createIfNeeded)
-public static void setThreadDefaultBus(Bus bus)</programlisting>
- </informalexample>
- <para>
- Please note that the default behaviour of
- <code>getDefaultBus()</code>
- <emphasis role="italics">/</emphasis>
- <code>getDefaultBus(true)</code>
- <emphasis role="italics">/</emphasis>
- <code>getThreadDefaultBus()</code>
- <emphasis role="italics">/</emphasis>
- <code>getThreadDefaultBus(true)</code>
- is to create a new Bus instance if that's not set yet. Moreover
- <emphasis
role="italics">getThreadDefaultBus()</emphasis>
- and
- <emphasis
role="italics">getThreadDefaultBus(true)</emphasis>
- first fallback to retrieving the configured global default bus before actually
trying creating a new instance (and the created new instance is set as global default bus
if that was not there set yet).
- </para>
- <para>The drawback of this mechanism (which is basically fine in JSE
environment) is that when running in a JBoss AS container you need to be careful in
order not to (mis)use a bus over multiple applications (assuming the Apache CXF classes
are loaded by the same classloader, which is currently the case with AS6 and
7).</para>
- <para>Here is a list of general suggestions to avoid problems when running
in-container:</para>
- <itemizedlist>
- <listitem>
- <para>
- forget about the global default bus; you don't need that, so don't
do
- <code>getDefaultBus()</code>
- <emphasis role="italics">/</emphasis>
- <code>getDefaultBus(true)</code>
- <emphasis role="italics">/</emphasis>
- <code>setDefaultBus()</code>
- in your code;
- </para>
- </listitem>
- <listitem>
- <para>
- avoid
- <code>getThreadDefaultBus()</code>
- <emphasis role="italics">/</emphasis>
- <code>getThreadDefaultBus(true)</code>
- unless you already know for sure the default bus is already set;
- </para>
- </listitem>
- <listitem>
- <para>keep in mind thread pooling whenever you customize a thread
default bus instance (for instance adding bus scope interceptors, ...), as that thread
and bus might be later reused; so either shutdown the bus when you're done or
explicitly remove it from the BusFactory thread association.</para>
- </listitem>
- </itemizedlist>
- <para>
- Finally, remember that each time you explictly create a new Bus instance
(factory.createBus()) that is set as thread default bus and global default bus if those
are not set yet. The JAXWS
- <code>Provider</code>
- implementation also creates
- <code>Bus</code>
- instances internally, in particular the JBossWS version of JAXWS
- <code>Provider</code>
- makes sure the default bus is never internally used and instead a new
- <code>Bus</code>
- is created if required.
- </para>
+public static void setThreadDefaultBus(Bus bus)
+</programlisting>
+ </informalexample>
+ <para>
+ Please note that the default behaviour of
+ <code>getDefaultBus()</code>
+ <emphasis role="italics">/</emphasis>
+ <code>getDefaultBus(true)</code>
+ <emphasis role="italics">/</emphasis>
+ <code>getThreadDefaultBus()</code>
+ <emphasis role="italics">/</emphasis>
+ <code>getThreadDefaultBus(true)</code>
+ is to create a new Bus instance if that's not set yet. Moreover
+ <emphasis
role="italics">getThreadDefaultBus()</emphasis>
+ and
+ <emphasis
role="italics">getThreadDefaultBus(true)</emphasis>
+ first fallback to retrieving the configured global default bus before
actually trying creating a new instance (and the created new instance is set as global
default bus if that was not there set yet).
+ </para>
+ <para>The drawback of this mechanism (which is basically fine in JSE
environment) is that when running in a JBoss AS container you need to be careful in
order not to (mis)use a bus over multiple applications (assuming the Apache CXF classes
are loaded by the same classloader, which is currently the case with AS6 and
7).</para>
+ <para>Here is a list of general suggestions to avoid problems when
running in-container:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ forget about the global default bus; you don't need that, so
don't do
+ <code>getDefaultBus()</code>
+ <emphasis role="italics">/</emphasis>
+ <code>getDefaultBus(true)</code>
+ <emphasis role="italics">/</emphasis>
+ <code>setDefaultBus()</code>
+ in your code;
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ avoid
+ <code>getThreadDefaultBus()</code>
+ <emphasis role="italics">/</emphasis>
+ <code>getThreadDefaultBus(true)</code>
+ unless you already know for sure the default bus is already set;
+ </para>
+ </listitem>
+ <listitem>
+ <para>keep in mind thread pooling whenever you customize a thread
default bus instance (for instance adding bus scope interceptors, ...), as that thread
and bus might be later reused; so either shutdown the bus when you're done or
explicitly remove it from the BusFactory thread association.</para>
+ </listitem>
+ </itemizedlist>
+ <para>
+ Finally, remember that each time you explictly create a new Bus instance
(factory.createBus()) that is set as thread default bus and global default bus if those
are not set yet. The JAXWS
+ <code>Provider</code>
+ implementation also creates
+ <code>Bus</code>
+ instances internally, in particular the JBossWS version of JAXWS
+ <code>Provider</code>
+ makes sure the default bus is never internally used and instead a new
+ <code>Bus</code>
+ is created if required.
+ </para>
+ </section>
</section>
<section
id="sid-3866786_ApacheCXFintegration-ServerSideIntegrationCustomization">
@@ -349,37 +899,174 @@
instance, of course) for the ws endpoint deployment.
</para>
<para>
- It is possible to customize the JBossWS and CXF integration by incorporating
the CXF configuration file to the endpoint deployment archive. In order for that to be
possible, JBossWS-CXF requires Spring to be installed in the application server. The
Spring Framework libraries installation can be perfomed using the JBossWS-CXF installation
or by manually populating the
- <emphasis
role="italics">org.springframework.spring</emphasis>
- module that's in JBoss AS 7 and which the other webservices modules already
have an optional dependency on.
+ While JBossWS sets sensible defaults for most of the Apache CXF configuration
options on server side, users might want to fine tune the
+ <code>Bus</code>
+ instance that's created for their deployments.
</para>
- <para>The convention is the following:</para>
- <itemizedlist>
- <listitem>
+ <section
id="sid-3866786_ApacheCXFintegration-Deploymentdescriptorproperties">
+
+ <title>Deployment descriptor properties</title>
+ <para>
+ The
+ <code>jboss-webservices.xml</code>
+ descriptor can be used to
+ <link linkend="sid-3866738">provide property
values</link>
+ .
+ </para>
+ <informalexample>
+ <programlisting><webservices
xmlns="http://www.jboss.com/xml/ns/javaee" version="1.2">
+ ...
+ <property>
+ <name>...</name>
+ <value>...</value>
+ </property>
+ ...
+</webservices></programlisting>
+ </informalexample>
+ <para>JBossWS-CXF integration comes with a set of allowed property names
to control Apache CXF internals. The main advantage of the property based approach is that
it does not require Spring libraries.</para>
+ <section
id="sid-3866786_ApacheCXFintegration-WorkQueueconfiguration">
+
+ <title>WorkQueue configuration</title>
<para>
- file name must be
- <emphasis role="strong">jbossws-cxf.xml</emphasis>
+ Apache CXF uses WorkQueue instances for dealing with some operations (e.g.
@Oneway requests processing). A
+ <ulink
url="http://cxf.apache.org/javadoc/latest-2.5.x/org/apache/cxf/workq...
+ is installed in the Bus as an extension and allows for adding / removing
queues as well as controlling the existing ones.
</para>
- </listitem>
- <listitem>
<para>
- for POJO deployments it is located in
- <emphasis role="strong">WEB-INF</emphasis>
- directory
+ On server side, queues can be provided through
+ <emphasis role="italics">Spring</emphasis>
+ based Bus declaration or by using the
+ <code>cxf.queue.<queue-name>.*</code>
+ properties in
+ <code>jboss-webservices.xml</code>
+ (e.g.
+ <code>cxf.queue.default.maxQueueSize</code>
+ for controlling the max queue size of the
+ <code>default</code>
+ workqueue). At deployment time, the JBossWS integration can add new
instances of
+ <ulink
url="http://cxf.apache.org/javadoc/latest-2.5.x/org/apache/cxf/workq...
+ to the currently configured WorkQueueManager; the properties below are used
to fill in parameter into the
+ <ulink
url="http://cxf.apache.org/javadoc/latest-2.5.x/org/apache/cxf/workq...,
int, int, int, long, java.lang.String)">AutomaticWorkQueueImpl
constructor</ulink>
+ :
</para>
- </listitem>
- <listitem>
+ <informaltable>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>
+ <para>Property</para>
+ </entry>
+ <entry>
+ <para>Default value</para>
+ </entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <para>
+
<code>cxf.queue.<queue-name>.maxQueueSize</code>
+ </para>
+ </entry>
+ <entry>
+ <para>256</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+
<code>cxf.queue.<queue-name>.initialThreads</code>
+
+ </para>
+ </entry>
+ <entry>
+ <para>0</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+
<code>cxf.queue.<queue-name>.highWaterMark</code>
+
+ </para>
+ </entry>
+ <entry>
+ <para>25</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+
<code>cxf.queue.<queue-name>.lowWaterMark</code>
+
+ </para>
+ </entry>
+ <entry>
+ <para>5</para>
+ </entry>
+ </row>
+ <row>
+ <entry>
+ <para>
+
<code>cxf.queue.<queue-name>.dequeueTimeout</code>
+
+ </para>
+ </entry>
+ <entry>
+ <para>120000</para>
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </section>
+ <section
id="sid-3866786_ApacheCXFintegration-Policyalternativeselector">
+
+ <title>Policy alternative selector</title>
<para>
- for EJB3 deployments it is located in
- <emphasis role="strong">META-INF</emphasis>
- directory
+ The Apache CXF policy engine supports different strategies to deal with
policy alternatives. JBossWS-CXF integration currently defaults to the
+ <ulink
url="http://cxf.apache.org/javadoc/latest-2.5.x/org/apache/cxf/ws/po...
+ , but still allows for setting different selector implementation using the
+ <code>cxf.policy.alternativeSelector</code>
+ property in
+ <code>jboss-webservices.xml</code>
+ .
</para>
- </listitem>
- </itemizedlist>
- <para>Providing custom CXF configuration to the endpoint deployment is
useful in cases when users want to use features that are not part of standard JAX-WS
specification (CXF specific) and that can't be setup in the application classes'
code. An example are some advanced WS-RM customizations.</para>
- <note>
- <para>Please consider that from a technical point of view, the
jbossws-cxf.xml configuration file is basically treated as an addition to the default
Apache CXF / JBossWS-CXF configuration. Hence users should be careful when dealing with
global configurations (eg. global bus level interceptors) and instead provide those
configuration in the deployment in another cxf.xml descriptor, which will be loaded at the
same time as the default setup.</para>
- </note>
+ </section>
+ </section>
+ <section
id="sid-3866786_ApacheCXFintegration-Springbasedconfiguration">
+
+ <title>Spring based configuration</title>
+ <para>
+ It is possible to customize the JBossWS and CXF integration by incorporating
the CXF configuration file to the endpoint deployment archive. In order for that to be
possible, JBossWS-CXF requires Spring to be installed in the application server. The
Spring Framework libraries installation can be performed using the JBossWS-CXF
installation or by manually populating the
+ <emphasis
role="italics">org.springframework.spring</emphasis>
+ module that's in JBoss AS 7 and which the other webservices modules
already have an optional dependency on.
+ </para>
+ <para>The convention is the following:</para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ file name must be
+ <emphasis role="strong">jbossws-cxf.xml</emphasis>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ for POJO deployments it is located in
+ <emphasis role="strong">WEB-INF</emphasis>
+ directory
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ for EJB3 deployments it is located in
+ <emphasis role="strong">META-INF</emphasis>
+ directory
+ </para>
+ </listitem>
+ </itemizedlist>
+ <para>Providing custom CXF configuration to the endpoint deployment is
useful in cases when users want to use features that are not part of standard JAX-WS
specification (CXF specific) and that can't be setup in the application classes'
code. An example are some advanced WS-RM customizations.</para>
+ </section>
</section>
</section>
<section id="sid-3866793">
@@ -664,7 +1351,7 @@
<para>Recent versions of Apache CXF, however, introduced support for
WS-Security Policy, which aims at moving most of the security configuration into the
service contract (through policies), so that clients can easily be configured almost
completely automatically from that. This way users do not need to manually deal with
configuring / installing the required interceptors; the Apache CXF WS-Policy engine
internally takes care of that instead.</para>
<section id="sid-3866795_WS-Security-WSSecurityPolicysupport">
- <title>WS-Security Policy support</title>
+ <title>Security Policy support</title>
<para>
WS-SecurityPolicy describes the actions that are required to securely
communicate with a service advertised in a given WSDL contract. The WSDL bindings /
operations reference WS-Policy fragments with the security requirements to interact with
the service. The
<ulink
url="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/v1.3/ws-secu...
specification</ulink>
@@ -763,7 +1450,8 @@
<informalexample>
<programlisting>Map<String, Object> ctx =
((BindingProvider)port).getRequestContext();
ctx.put("ws-security.encryption.properties", properties);
-port.echoString("hello");</programlisting>
+port.echoString("hello");
+</programlisting>
</informalexample>
<para>
Please refer to the
@@ -778,9 +1466,11 @@
<para>
In order for removing the need of Spring on server side for setting up
WS-Security configuration properties not covered by policies, the JBossWS integration
allows for getting those pieces of information from a defined
<emphasis role="italics">endpoint
configuration</emphasis>
- . Endpoint configurations can include property declarations and endpoint
implementations can be associated with a given endpoint configuration using the
+ .
+ <link linkend="sid-41713670">Endpoint
configurations</link>
+ can include property declarations and endpoint implementations can be
associated with a given endpoint configuration using the
<code>@EndpointConfig</code>
- annotation. While endpoint configurations can be provided through the JBoss
Application Server 7 domain, for the sake of WS-Security configuration they're
probably better described in a deployment descriptor included in the deployed archive:
+ annotation.
</para>
<informalexample>
<programlisting><?xml version="1.0"
encoding="UTF-8"?>
@@ -1049,7 +1739,7 @@
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</programlisting>
+org.apache.ws.security.crypto.merlin.keystore.file=bob.jks</programlisting>
</informalexample>
<para>A callback handler for the letting Apache CXF access the keystore
is also provided:</para>
<informalexample>
@@ -1214,7 +1904,7 @@
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=META-INF/alice.jks</programlisting>
+org.apache.ws.security.crypto.merlin.keystore.file=META-INF/alice.jks</programlisting>
</informalexample>
<para>The Apache CXF WS-Policy engine will digest the security
requirements in the contract and ensure a valid secure communication is in place for
interacting with the server endpoint.</para>
</section>
@@ -1704,8 +2394,1000 @@
</web-app></programlisting>
</informalexample>
</section>
+ <section id="sid-3866795_WS-Security-Secureconversation">
+
+ <title>Secure conversation</title>
+ <para>
+ Apache CXF supports
+ <ulink
url="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512/w...
+ specification, which is about improving performance by allowing client and
server to negotiate initial security keys to be used for later communication
encryption/signature. This is done by having two policies in the wsdl contract, an outer
one setting the security requirements to actually communicate with the endpoint and a
bootstrap one, related to the communication for establishing the secure conversation keys.
The client will be automatically sending an initial message to the server for negotiating
the keys, then the actual communication to the endpoint takes place. As a consequence,
Apache CXF needs a way to specify which WS-Security configuration properties are intended
for the bootstrap policy and which are intended for the actual service policy. To
accomplish this, properties intended for the bootstrap policy are appended with
+ <code>.sct</code>
+ .
+ </para>
+ <informalexample>
+ <programlisting>...
+((BindingProvider)proxy).getRequestContext().put("ws-security.signature.username.sct",
"alice");
+((BindingProvider)proxy).getRequestContext().put("ws-security.encryption.username.sct",
"bob");
+...</programlisting>
+ </informalexample>
+ <informalexample>
+ <programlisting>@WebService(
+ ...
+)
+@EndpointProperties(value = {
+ @EndpointProperty(key = "ws-security.encryption.properties.sct", value =
"bob.properties"),
+ @EndpointProperty(key = "ws-security.signature.properties.sct", value =
"bob.properties"),
+ ...
+ }
+)
+public class ServiceImpl implements ServiceIface {
+ ...
+}</programlisting>
+ </informalexample>
+ </section>
</section>
</section>
+ <section id="sid-47972359">
+
+ <title>WS-Trust and STS</title>
+ <section id="sid-47972359_WS-TrustandSTS-WSTrustoverview">
+
+ <title>WS-Trust overview</title>
+ <para>
+ The
+ <ulink
url="https://www.oasis-open.org/standards#wstrustv1.4">WS-Tr...
+ specification defines extensions to WS-Security to deal with the issuing,
renewing, and validating of security tokens; it also defines how to establish, assess the
presence of, and broker trust relationships between participants in a secure message
exchange.
+ </para>
+ <para>
+ Complex applications spanning multiple domains typically suffer from the need
for generating and sharing multiple keys; moreover dealing with services updates when
credentials change is usually painful. With WS-Trust, a trusted
+ <emphasis role="italics">Security Token Service
(STS)</emphasis>
+ can be used to obtain security tokens which are then used as authentication /
authorization. A client authenticates itself with the STS based on policies and
requirements defined by the STS; the STS then provides a security token (e.g. a SAML
token) that the client then uses to talk to the target service; the service can validate
that token to make sure it really came from the trusted STS.
+ </para>
+ </section>
+ <section id="sid-47972359_WS-TrustandSTS-SecurityTokenService">
+
+ <title>Security Token Service</title>
+ <para>The security token service is the core of the WS-Trust extension to
WS-Security; it is a service that offers some or all of the following
functionalities:</para>
+ <itemizedlist>
+ <listitem>
+ <para>issuing security tokens of different types depending on the
received credentials</para>
+ </listitem>
+ <listitem>
+ <para>validation of security tokens</para>
+ </listitem>
+ <listitem>
+ <para>renewal of security tokens</para>
+ </listitem>
+ <listitem>
+ <para>cancellation of security tokens</para>
+ </listitem>
+ <listitem>
+ <para>transformation of security tokens into different type
ones</para>
+ </listitem>
+ </itemizedlist>
+ <para>In the basic scenario, the WSDL contract for an endpoint service will
usually include a WS-Security policy stating that a particular security token type is
required to access the service. Clients reading that contract will ask the STS for a
security token of the required type and attach it to the message invocation to the
service. The endpoint service will locally validate the received token or dispatch it to
the STS for validation.</para>
+ </section>
+ <section id="sid-47972359_WS-TrustandSTS-ApacheCXFsupport">
+
+ <title>Apache CXF support</title>
+ <para>
+ JBossWS inherits Apache CXF support for WS-Trust, which is fully integration
with WS-Security Policy support. On client side, a
+ <code>STSClient</code>
+ is used to contact the STS and e.g get the security token; the
+ <code>STSClient</code>
+ can either be programmatically provided or automatically created by CXF runtime
(through policy support) and configured through properties as done with plain WS-Security
(keystore locations, aliases, etc.).
+ </para>
+ <para>
+ Any specification compliant STS can be used; however Apache CXF comes with its
own STS implementation, which can be deployed on JBoss Application Server using JBossWS
integration too. Detailed information on the Apache CXF STS implementation in a multiple
blog post series
+ <ulink
url="http://coheigea.blogspot.it/2011/10/apache-cxf-sts-documentation-part-i.html">here</ulink>
+ .
+ </para>
+ </section>
+ <section id="sid-47972359_WS-TrustandSTS-Example">
+
+ <title>Example</title>
+ <para>
+ Here is an example of a basic WS-Trust scenario. A service provider published a
WSDL with policy assertions establishing who the communication must happen. A SAML 2.0
token issued by an STS is required to access the service endpoint. The client will
authenticate itself to the STS using a UsernameToken over the symmetric binding and the
STS will issue it the desired SAML 2.0 token, which the client will then forwards to the
service provider endpoint. As the
+ <code>IssuedToken</code>
+ is defined as the
+ <code>InitiatorToken</code>
+ of the Asymmetric binding in the policy of the service provider, the client
will use the associated secret key for message signing.
+ </para>
+ <section id="sid-47972359_WS-TrustandSTS-Endpoint">
+
+ <title>Endpoint</title>
+ <para>The service provider is a contract-first endpoint and the need for
WS-Trust communication is completely driven by the wsdl. It comes with policies requiring
signature and encryption of messages and setting the WS-Trust requirements (SAML 2.0
security token and STS location). WS-AddressingMetadata is used to specify the wsdl
location of the STS and the servive/port name in it to be used:</para>
+ <informalexample>
+ <programlisting><?xml version="1.0"
encoding="UTF-8" standalone="yes"?>
+<definitions
targetNamespace="http://www.jboss.org/jbossws/ws-extensions/wssecuri...
name="SecurityService"
+
xmlns:tns="http://www.jboss.org/jbossws/ws-extensions/wssecuritypoli...
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+
xmlns="http://schemas.xmlsoap.org/wsdl/"
+
xmlns:wsp="http://www.w3.org/ns/ws-policy"
+
xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
+
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-w...
+
xmlns:wsaws="http://www.w3.org/2005/08/addressing"
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+
xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
+ <types>
+ <xsd:schema>
+ <xsd:import
namespace="http://www.jboss.org/jbossws/ws-extensions/wssecuritypoli...
schemaLocation="SecurityService_schema1.xsd"/>
+ </xsd:schema>
+ </types>
+ <message name="sayHello">
+ <part name="parameters" element="tns:sayHello"/>
+ </message>
+ <message name="sayHelloResponse">
+ <part name="parameters"
element="tns:sayHelloResponse"/>
+ </message>
+ <portType name="ServiceIface">
+ <operation name="sayHello">
+ <input message="tns:sayHello"/>
+ <output message="tns:sayHelloResponse"/>
+ </operation>
+ </portType>
+ <binding name="SecurityServicePortBinding"
type="tns:ServiceIface">
+ <wsp:PolicyReference URI="#AsymmetricSAML2Policy" />
+ <soap:binding
transport="http://schemas.xmlsoap.org/soap/http"
style="document"/>
+ <operation name="sayHello">
+ <soap:operation soapAction=""/>
+ <input>
+ <soap:body use="literal"/>
+ <wsp:PolicyReference URI="#Input_Policy" />
+ </input>
+ <output>
+ <soap:body use="literal"/>
+ <wsp:PolicyReference URI="#Output_Policy" />
+ </output>
+ </operation>
+ </binding>
+ <service name="SecurityService">
+ <port name="SecurityServicePort"
binding="tns:SecurityServicePortBinding">
+ <soap:address
location="http://localhost:8080/jaxws-samples-wsse-policy-trust/SecurityService"/>
+ </port>
+ </service>
+
+ <wsp:Policy wsu:Id="AsymmetricSAML2Policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <wsam:Addressing wsp:Optional="false">
+ <wsp:Policy />
+ </wsam:Addressing>
+ <sp:AsymmetricBinding>
+ <wsp:Policy>
+ <sp:InitiatorToken>
+ <wsp:Policy>
+ <sp:IssuedToken
+
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/...
+ <sp:RequestSecurityTokenTemplate>
+ <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
+ <t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey</t:KeyType>
+ </sp:RequestSecurityTokenTemplate>
+ <wsp:Policy>
+ <sp:RequireInternalReference />
+ </wsp:Policy>
+ <sp:Issuer>
+ <wsaws:Address>http://localhost:8080/jaxws-samples-wsse-policy-trust-sts/SecurityTokenService</wsaws:Address>
+ <wsaws:Metadata
xmlns:wsdli="http://www.w3.org/2006/01/wsdl-instance"
+
wsdli:wsdlLocation="http://localhost:8080/jaxws-samples-wsse-policy-trust-sts/SecurityTokenService?wsdl">
+ <wsaw:ServiceName
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
+
xmlns:stsns="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
+
EndpointName="UT_Port">stsns:SecurityTokenService</wsaw:ServiceName>
+ </wsaws:Metadata>
+ </sp:Issuer>
+ </sp:IssuedToken>
+ </wsp:Policy>
+ </sp:InitiatorToken>
+ <sp:RecipientToken>
+ <wsp:Policy>
+ <sp:X509Token
+
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/...
+ <wsp:Policy>
+ <sp:WssX509V3Token10 />
+ <sp:RequireIssuerSerialReference />
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:RecipientToken>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Lax />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:OnlySignEntireHeadersAndBody />
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ </wsp:Policy>
+ </sp:AsymmetricBinding>
+ <sp:Wss11>
+ <wsp:Policy>
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust13>
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust13>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+
+ <wsp:Policy wsu:Id="Input_Policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:EncryptedParts>
+ <sp:Body />
+ </sp:EncryptedParts>
+ <sp:SignedParts>
+ <sp:Body />
+ <sp:Header Name="To"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action"
Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+
+ <wsp:Policy wsu:Id="Output_Policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:EncryptedParts>
+ <sp:Body />
+ </sp:EncryptedParts>
+ <sp:SignedParts>
+ <sp:Body />
+ <sp:Header Name="To"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo"
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action"
Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+</definitions></programlisting>
+ </informalexample>
+ <para>
+ The endpoint implementation class is a POJO featuring Apache CXF
+ <code>@EndpointProperty</code>
+ annotations to provide
+ <emphasis role="italics">WSS4J</emphasis>
+ security properties:
+ </para>
+ <informalexample>
+ <programlisting>package
org.jboss.test.ws.jaxws.samples.wsse.policy.trust;
+
+import javax.jws.WebService;
+
+import org.apache.cxf.annotations.EndpointProperties;
+import org.apache.cxf.annotations.EndpointProperty;
+
+@WebService
+(
+ portName = "SecurityServicePort",
+ serviceName = "SecurityService",
+ wsdlLocation = "WEB-INF/wsdl/SecurityService.wsdl",
+ targetNamespace =
"http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy",
+ endpointInterface =
"org.jboss.test.ws.jaxws.samples.wsse.policy.trust.ServiceIface"
+)
+@EndpointProperties(value = {
+ @EndpointProperty(key = "ws-security.signature.username", value =
"myservicekey"),
+ @EndpointProperty(key = "ws-security.signature.properties", value =
"serviceKeystore.properties"),
+ @EndpointProperty(key = "ws-security.encryption.properties", value =
"serviceKeystore.properties"),
+ @EndpointProperty(key = "ws-security.callback-handler", value =
"org.jboss.test.ws.jaxws.samples.wsse.policy.trust.ServerCallbackHandler")
+})
+public class ServiceImpl implements ServiceIface
+{
+ public String sayHello()
+ {
+ return "WS-Trust Hello World!";
+ }
+}</programlisting>
+ </informalexample>
+ <para>
+ ... the
+ <emphasis
role="italics">serviceKeystore.properties</emphasis>
+ file references the keystore, aliases, etc.
+ </para>
+ <informalexample>
+
<programlisting>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=sspass
+org.apache.ws.security.crypto.merlin.keystore.alias=myservicekey
+org.apache.ws.security.crypto.merlin.keystore.file=servicestore.jks</programlisting>
+ </informalexample>
+ <para>
+ ... while
+ <code>ServerCallbackHandler</code>
+ is an usual implementation of
+ <code>CallbackHandler</code>
+ to allow Apache CXF access to the keystore:
+ </para>
+ <informalexample>
+ <programlisting>package
org.jboss.test.ws.jaxws.samples.wsse.policy.trust;
+
+import java.io.IOException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.apache.ws.security.WSPasswordCallback;
+
+public class ServerCallbackHandler implements CallbackHandler {
+
+ public void handle(Callback[] callbacks) throws IOException,
+ UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ if (callbacks[i] instanceof WSPasswordCallback) {
+ WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+ if ("myservicekey".equals(pc.getIdentifier())) {
+ pc.setPassword("skpass");
+ break;
+ }
+ }
+ }
+ }
+}</programlisting>
+ </informalexample>
+ <para>
+ Assuming the
+ <emphasis role="italics">servicestore.jks</emphasis>
+ keystore has been properly generated and contains service provider (server)
full key (private/certificate + public key) as well as the STS public key, we can proceed
to packaging the endpoint. Here is the expected content (the endpoint is a
+ <emphasis role="italics">POJO</emphasis>
+ one in a
+ <emphasis role="italics">war</emphasis>
+ archive, but
+ <emphasis role="italics">EJB3</emphasis>
+ endpoints in
+ <emphasis role="italics">jar</emphasis>
+ archives are of course also supported):
+ </para>
+ <informalexample>
+ <programlisting>alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar
-tvf ./modules/testsuite/cxf-tests/target/test-libs/jaxws-samples-wsse-policy-trust.war
+ 0 Thu Jun 21 14:03:24 CEST 2012 META-INF/
+ 159 Thu Jun 21 14:03:22 CEST 2012 META-INF/MANIFEST.MF
+ 0 Thu Jun 21 14:03:24 CEST 2012 WEB-INF/
+ 0 Thu Jun 21 14:03:24 CEST 2012 WEB-INF/classes/
+ 0 Thu Jun 21 14:03:20 CEST 2012 WEB-INF/classes/org/
+ 0 Thu Jun 21 14:03:20 CEST 2012 WEB-INF/classes/org/jboss/
+ 0 Thu Jun 21 14:03:20 CEST 2012 WEB-INF/classes/org/jboss/test/
+ 0 Thu Jun 21 14:03:22 CEST 2012 WEB-INF/classes/org/jboss/test/ws/
+ 0 Thu Jun 21 14:03:20 CEST 2012 WEB-INF/classes/org/jboss/test/ws/jaxws/
+ 0 Thu Jun 21 14:03:20 CEST 2012 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
+ 0 Thu Jun 21 14:03:20 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
+ 0 Thu Jun 21 14:03:20 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/
+ 0 Thu Jun 21 14:03:22 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/
+ 705 Thu Jun 21 14:03:22 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/SayHello.class
+ 1069 Thu Jun 21 14:03:22 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/jaxws/SayHelloResponse.class
+ 0 Thu Jun 21 14:03:22 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/
+ 1159 Thu Jun 21 14:03:22 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/ServerCallbackHandler.class
+ 383 Thu Jun 21 14:03:20 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/ServiceIface.class
+ 1365 Thu Jun 21 14:03:20 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/ServiceImpl.class
+ 0 Thu Jun 21 14:03:18 CEST 2012 WEB-INF/wsdl/
+ 6478 Thu Jun 21 14:03:18 CEST 2012 WEB-INF/wsdl/SecurityService.wsdl
+ 653 Thu Jun 21 14:03:18 CEST 2012 WEB-INF/wsdl/SecurityService_schema1.xsd
+ 1121 Thu Jun 21 14:03:18 CEST 2012 WEB-INF/classes/serviceKeystore.properties
+ 3350 Thu Jun 21 14:03:18 CEST 2012
WEB-INF/classes/servicestore.jks</programlisting>
+ </informalexample>
+ <para>As you can see, the jaxws classes generated by the tools are of
course also included. The manifest declares the JBoss Modules dependencies for allowing
Apache CXF annotations and WSS4J usage:</para>
+ <informalexample>
+ <programlisting>Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.8.2
+Created-By: 1.6.0_26-b03 (Sun Microsystems Inc.)
+Dependencies: org.apache.ws.security,org.apache.cxf</programlisting>
+ </informalexample>
+ </section>
+ <section id="sid-47972359_WS-TrustandSTS-Client">
+
+ <title>Client</title>
+ <para>
+ You start by consuming the published WSDL contract using the
+ <emphasis role="italics">wsconsume</emphasis>
+ tool on client side too. Then you simply invoke the the endpoint as a
standard JAX-WS one:
+ </para>
+ <informalexample>
+ <programlisting>QName serviceName = new
QName("http://www.jboss.org/jbossws/ws-extensions/wssecuritypolicy",
"SecurityService");
+URL wsdlURL = new URL(serviceURL + "?wsdl");
+Service service = Service.create(wsdlURL, serviceName);
+ServiceIface proxy = (ServiceIface) service.getPort(ServiceIface.class);
+
+//setup WS-Security
+Map<String, Object> ctx = ((BindingProvider) proxy).getRequestContext();
+ctx.put(SecurityConstants.CALLBACK_HANDLER, new ClientCallbackHandler());
+ctx.put(SecurityConstants.SIGNATURE_PROPERTIES,
Thread.currentThread().getContextClassLoader().getResource("META-INF/clientKeystore.properties"));
+ctx.put(SecurityConstants.ENCRYPT_PROPERTIES,
Thread.currentThread().getContextClassLoader().getResource("META-INF/clientKeystore.properties"));
+ctx.put(SecurityConstants.SIGNATURE_USERNAME, "myclientkey");
+ctx.put(SecurityConstants.ENCRYPT_USERNAME, "myservicekey");
+ctx.put(SecurityConstants.USERNAME + ".it", "alice");
+ctx.put(SecurityConstants.CALLBACK_HANDLER + ".it", new
ClientCallbackHandler());
+ctx.put(SecurityConstants.ENCRYPT_PROPERTIES + ".it",
Thread.currentThread().getContextClassLoader().getResource("META-INF/clientKeystore.properties"));
+ctx.put(SecurityConstants.ENCRYPT_USERNAME + ".it", "mystskey");
+ctx.put(SecurityConstants.STS_TOKEN_USERNAME + ".it",
"myclientkey");
+ctx.put(SecurityConstants.STS_TOKEN_PROPERTIES + ".it",
Thread.currentThread().getContextClassLoader().getResource("META-INF/clientKeystore.properties"));
+ctx.put(SecurityConstants.STS_TOKEN_USE_CERT_FOR_KEYINFO + ".it",
"true");
+ctx.put("ws-security.sts.disable-wsmex-call-using-epr-address",
"true");
+
+proxy.sayHello();</programlisting>
+ </informalexample>
+ <para>
+ As you can see, as usual the WS-Security properties are set in the request
context. The
+ <code>".it"</code>
+ suffix is used for properties related to communication with the Security
Token Service (which is described below and also includes policies enforcing signed and
encrypted messages). The
+ <code>
+ <ulink
url="http://anonsvn.jboss.org/repos/jbossws/stack/cxf/tags/jbossws-c...
+ </code>
+ is basically similar to the endpoint server one. The
+ <emphasis
role="italics">clientKeystore.properties</emphasis>
+ file is the client side equivalent of the
+ <emphasis
role="italics">serviceKeystore.properties</emphasis>
+ and references the
+ <emphasis role="italics">clientstore.jks</emphasis>
+ keystore file, which has been populated with the client full key
(private/certificate + public key) as well as the server endpoint and STS public keys.
+ </para>
+ <informalexample>
+
<programlisting>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=cspass
+org.apache.ws.security.crypto.merlin.keystore.alias=myclientkey
+org.apache.ws.security.crypto.merlin.keystore.file=META-INF/clientstore.jks</programlisting>
+ </informalexample>
+ <para>The Apache CXF WS-Policy engine will digest the security
requirements in the endpoint contract and ensure a valid secure communication is in place
for interacting with the server endpoint. More in details, here is what will be
happening:</para>
+ <orderedlist>
+ <listitem>
+ <para>the client get the service endpoint WSDL; the Apache CXF engine
parses it, processes the included policy and decides to contact the STS</para>
+ </listitem>
+ <listitem>
+ <para>the STS client is automatically injected into the application
client and gets the STS wsdl; the Apache CXF engine processes the policy in
it</para>
+ </listitem>
+ <listitem>
+ <para>a WS-Security enabled communication (as per STS advertised
policy) is established and the client issues a request for getting a SAML assertion token
from the STS</para>
+ </listitem>
+ <listitem>
+ <para>the STS endpoint receives the request, extracts the client
identify from it and authenticates the client</para>
+ </listitem>
+ <listitem>
+ <para>the SAML token is returned to the client, which uses it for
establishing a new connection with the service endpoint; the Apache CXF engine again
setups signature/encryption as per endpoint advertised policy</para>
+ </listitem>
+ <listitem>
+ <para>the service endpoint receives the token provided through the
STS and performs the required operation</para>
+ </listitem>
+ </orderedlist>
+ </section>
+ <section id="sid-47972359_WS-TrustandSTS-ApacheCXFSTS">
+
+ <title>Apache CXF STS</title>
+ <para>
+ As mentioned above, Apache CXF comes with its own Security Token Service
implementation. That is completely configurable and can be used as a JAX-WS
+ <code>WebServiceProvider</code>
+ endpoint running in payload service mode. An extension to the
org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider is created, properly
annotated and included in an usual webservice endpoint deployment.
+ </para>
+ <informalexample>
+ <programlisting>package
org.jboss.test.ws.jaxws.samples.wsse.policy.trust;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.xml.ws.WebServiceProvider;
+
+import org.apache.cxf.annotations.EndpointProperties;
+import org.apache.cxf.annotations.EndpointProperty;
+import org.apache.cxf.interceptor.InInterceptors;
+import org.apache.cxf.sts.StaticSTSProperties;
+import org.apache.cxf.sts.operation.TokenIssueOperation;
+import org.apache.cxf.sts.operation.TokenValidateOperation;
+import org.apache.cxf.sts.service.ServiceMBean;
+import org.apache.cxf.sts.service.StaticService;
+import org.apache.cxf.sts.token.provider.SAMLTokenProvider;
+import org.apache.cxf.sts.token.validator.SAMLTokenValidator;
+import org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider;
+
+@WebServiceProvider(serviceName = "SecurityTokenService",
+ portName = "UT_Port",
+ targetNamespace = "http://docs.oasis-open.org/ws-sx/ws-trust/200512/",
+ wsdlLocation = "WEB-INF/wsdl/ws-trust-1.4-service.wsdl")
+@EndpointProperties(value = {
+ @EndpointProperty(key = "ws-security.signature.username", value =
"mystskey"),
+ @EndpointProperty(key = "ws-security.signature.properties", value =
"stsKeystore.properties"),
+ @EndpointProperty(key = "ws-security.callback-handler", value =
"org.jboss.test.ws.jaxws.samples.wsse.policy.trust.STSCallbackHandler"),
+ @EndpointProperty(key = "ws-security.validate.token", value =
"false") //to let the JAAS integration deal with validation through the
interceptor below
+})
+@InInterceptors(interceptors =
{"org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingPolicyInterceptor"})
+public class SampleSTS extends SecurityTokenServiceProvider
+{
+ public SampleSTS() throws Exception
+ {
+ super();
+
+ StaticSTSProperties props = new StaticSTSProperties();
+ props.setSignaturePropertiesFile("stsKeystore.properties");
+ props.setSignatureUsername("mystskey");
+ props.setCallbackHandlerClass(STSCallbackHandler.class.getName());
+ props.setIssuer("DoubleItSTSIssuer");
+
+ List<ServiceMBean> services = new
LinkedList<ServiceMBean>();
+ StaticService service = new StaticService();
+
service.setEndpoints(Arrays.asList("http://localhost:(\\d)*/jaxws-samples-wsse-policy-trust/SecurityService",
"http://\\[::1\\]:(\\d)*/jaxws-samples-wsse-policy-trust/SecurityService"));
+ services.add(service);
+
+ TokenIssueOperation issueOperation = new TokenIssueOperation();
+ issueOperation.setServices(services);
+ issueOperation.getTokenProviders().add(new SAMLTokenProvider());
+ issueOperation.setStsProperties(props);
+
+ TokenValidateOperation validateOperation = new TokenValidateOperation();
+ validateOperation.getTokenValidators().add(new SAMLTokenValidator());
+ validateOperation.setStsProperties(props);
+
+ this.setIssueOperation(issueOperation);
+ this.setValidateOperation(validateOperation);
+ }
+}</programlisting>
+ </informalexample>
+ <para>
+ The
+ <code>@WebServiceProvider</code>
+ annotation references a WS-SecurityPolicy enriched
+ <ulink
url="http://anonsvn.jboss.org/repos/jbossws/stack/cxf/tags/jbossws-c...
+ of the WS-Trust 1.4 wsdl.
+ </para>
+ <para>
+ The
+ <code>@EndpointProperty</code>
+ annotations provides the usual WSS4J configuration elements.
+ </para>
+ <para>
+ The
+ <code>@InInterceptor</code>
+ annotation is used to specify a JBossWS integration interceptor to be used
for authenticating incoming requests; JAAS integration is used here for authentication, so
basically the username/passoword coming from the UsernameToken in the client message are
used for authenticating the client against a security domain on the application server
hosting the STS deployment.
+ </para>
+ <para>The stsKeystore.properties file is as follows:</para>
+ <informalexample>
+
<programlisting>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=stsspass
+org.apache.ws.security.crypto.merlin.keystore.file=stsstore.jks</programlisting>
+ </informalexample>
+ <para>... while STSCallbackHandler grants access to the stsstore.jks,
which has been populated with the STS full key (private/certificate + public key) as well
as the server endpoint and client public keys.</para>
+ <informalexample>
+ <programlisting>package
org.jboss.test.ws.jaxws.samples.wsse.policy.trust;
+
+import java.io.IOException;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import org.apache.ws.security.WSPasswordCallback;
+
+public class STSCallbackHandler implements CallbackHandler {
+
+ public void handle(Callback[] callbacks) throws IOException,
+ UnsupportedCallbackException {
+ for (int i = 0; i < callbacks.length; i++) {
+ if (callbacks[i] instanceof WSPasswordCallback) {
+ WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
+ if ("mystskey".equals(pc.getIdentifier())) {
+ pc.setPassword("stskpass");
+ break;
+ }
+ }
+ }
+ }
+}</programlisting>
+ </informalexample>
+ <para>Here is how the STS webservice provider is packaged:</para>
+ <informalexample>
+ <programlisting>alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar
-tvf
./modules/testsuite/cxf-tests/target/test-libs/jaxws-samples-wsse-policy-trust-sts.war
+ 0 Mon Jun 25 13:39:06 CEST 2012 META-INF/
+ 164 Mon Jun 25 13:39:04 CEST 2012 META-INF/MANIFEST.MF
+ 0 Mon Jun 25 13:39:06 CEST 2012 WEB-INF/
+ 0 Mon Jun 25 13:39:06 CEST 2012 WEB-INF/classes/
+ 0 Mon Jun 25 13:39:04 CEST 2012 WEB-INF/classes/org/
+ 0 Mon Jun 25 13:39:04 CEST 2012 WEB-INF/classes/org/jboss/
+ 0 Mon Jun 25 13:39:04 CEST 2012 WEB-INF/classes/org/jboss/test/
+ 0 Mon Jun 25 13:39:04 CEST 2012 WEB-INF/classes/org/jboss/test/ws/
+ 0 Mon Jun 25 13:39:04 CEST 2012 WEB-INF/classes/org/jboss/test/ws/jaxws/
+ 0 Mon Jun 25 13:39:04 CEST 2012 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
+ 0 Mon Jun 25 13:39:04 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
+ 0 Mon Jun 25 13:39:04 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/
+ 0 Mon Jun 25 13:39:04 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/
+ 1148 Mon Jun 25 13:39:04 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/STSCallbackHandler.class
+ 3456 Mon Jun 25 13:39:04 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/SampleSTS.class
+ 251 Mon Jun 25 13:39:02 CEST 2012 WEB-INF/jboss-web.xml
+ 0 Mon Jun 25 13:39:02 CEST 2012 WEB-INF/wsdl/
+ 13635 Mon Jun 25 13:39:02 CEST 2012 WEB-INF/wsdl/ws-trust-1.4-service.wsdl
+ 1054 Mon Jun 25 13:39:02 CEST 2012 WEB-INF/classes/stsKeystore.properties
+ 3978 Mon Jun 25 13:39:02 CEST 2012 WEB-INF/classes/stsstore.jks</programlisting>
+ </informalexample>
+ <para>
+ The
+ <emphasis role="italics">jboss-web.xml</emphasis>
+ descriptor is used to set the security domain to be used for authentication
(in this case the domain will need to be configured to allow
+ <emphasis role="italics">alice</emphasis>
+ /
+ <emphasis role="italics">clarinet</emphasis>
+ username/password couple):
+ </para>
+ <informalexample>
+ <programlisting><?xml version="1.0"
encoding="UTF-8"?>
+<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.4//EN"
"http://www.jboss.org/j2ee/dtd/jboss-web_4_0.dtd">
+<jboss-web>
+
<security-domain>java:/jaas/JBossWS-trust-sts</security-domain>
+</jboss-web></programlisting>
+ </informalexample>
+ <para>
+ ... and the manifest contains the usual declaration of JBoss Application
Server 7 module dependencies (Apache CXF internals are needed here to build up the STS
configuration in
+ <code>SampleSTS</code>
+ constructor as shown above):
+ </para>
+ <informalexample>
+ <programlisting>Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.8.2
+Created-By: 1.6.0_26-b03 (Sun Microsystems Inc.)
+Dependencies: org.apache.ws.security,org.apache.cxf.impl</programlisting>
+ </informalexample>
+ <tip>
+ <title>WS-MetadataExchange and interoperability</title>
+ <para>
+ To achieve better interoperability, you might consider allowing the STS
endpoint to reply to WS-MetadataExchange messages directed to the
+ <code>/mex</code>
+ URL sub-path (e.g.
+ <code>
+ <ulink
url="http://localhost:8080/jaxws-samples-wsse-policy-trust-sts/SecurityTokenService/mex"/>
+ </code>
+ ). This can be done by tweaking the
+ <emphasis role="italics">url-pattern</emphasis>
+ for the underlying endpoint servlet, for instance by adding a
+ <emphasis role="italics">web.xml</emphasis>
+ descriptor as follows to the deployment:
+
+ </para>
+ <informalexample>
+ <programlisting><?xml version="1.0"
encoding="UTF-8"?>
+<web-app
+ version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
+ <servlet>
+ <servlet-name>TestSecurityTokenService</servlet-name>
+
<servlet-class>org.jboss.test.ws.jaxws.samples.wsse.policy.trust.SampleSTS</servlet-class>
+ </servlet>
+ <servlet-mapping>
+ <servlet-name>TestSecurityTokenService</servlet-name>
+ <url-pattern>/SecurityTokenService/*</url-pattern>
+ </servlet-mapping>
+</web-app></programlisting>
+ </informalexample>
+ <para>
+ As a matter of fact, at the time of writing some webservices
implementations (including
+ <emphasis role="italics">Metro</emphasis>
+ ) assume the
+ <code>/mex</code>
+ URL as the default choice for directing WS-MetadataExchange requests to and
use that to retrieve STS wsdl contracts.
+ </para>
+ </tip>
+ </section>
+ <section id="sid-47972359_WS-TrustandSTS-PicketLinkSTS">
+
+ <title>PicketLink STS</title>
+ <para>
+ <ulink
url="http://www.jboss.org/picketlink">PicketLink</ulink>
+ provides facilities for building up an alternative to the Apache CXF Security
Token Service implementation.
+ </para>
+ <para>
+ Similarly to the previous implementation, the STS is served through a
+ <code>WebServiceProvider</code>
+ annotated POJO:
+ </para>
+ <informalexample>
+ <programlisting>package
org.jboss.test.ws.jaxws.samples.wsse.policy.trust;
+
+import javax.annotation.Resource;
+import javax.xml.ws.Service;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.WebServiceProvider;
+
+import org.apache.cxf.annotations.EndpointProperties;
+import org.apache.cxf.annotations.EndpointProperty;
+import org.apache.cxf.interceptor.InInterceptors;
+import org.picketlink.identity.federation.core.wstrust.PicketLinkSTS;
+
+@WebServiceProvider(serviceName = "PicketLinkSTS", portName =
"PicketLinkSTSPort", targetNamespace =
"urn:picketlink:identity-federation:sts", wsdlLocation =
"WEB-INF/wsdl/PicketLinkSTS.wsdl")
+@ServiceMode(value = Service.Mode.MESSAGE)
+//be sure to have dependency on org.apache.cxf module when on AS7, otherwise Apache CXF
annotations are ignored
+@EndpointProperties(value = {
+ @EndpointProperty(key = "ws-security.signature.username", value =
"mystskey"),
+ @EndpointProperty(key = "ws-security.signature.properties", value =
"stsKeystore.properties"),
+ @EndpointProperty(key = "ws-security.callback-handler", value =
"org.jboss.test.ws.jaxws.samples.wsse.policy.trust.STSCallbackHandler"),
+ @EndpointProperty(key = "ws-security.validate.token", value =
"false") //to let the JAAS integration deal with validation through the
interceptor below
+})
+@InInterceptors(interceptors =
{"org.jboss.wsf.stack.cxf.security.authentication.SubjectCreatingPolicyInterceptor"})
+public class PicketLinkSTService extends PicketLinkSTS {
+ @Resource
+ public void setWSC(WebServiceContext wctx) {
+ this.context = wctx;
+ }
+}</programlisting>
+ </informalexample>
+ <para>
+ The
+ <code>@WebServiceProvider</code>
+ annotation references the following WS-Policy enabled wsdl contract; please
note the wsdl operations, messages and such must match the
+ <code>PicketLinkSTS</code>
+ implementation:
+ </para>
+ <informalexample>
+ <programlisting><?xml version="1.0"?>
+<wsdl:definitions name="PicketLinkSTS"
targetNamespace="urn:picketlink:identity-federation:sts"
+ xmlns:tns="urn:picketlink:identity-federation:sts"
+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+
xmlns:wsap10="http://www.w3.org/2006/05/addressing/wsdl"
+
xmlns:wsp="http://www.w3.org/ns/ws-policy"
+
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-w...
+
xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
+
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/">
+ <wsdl:types>
+ <xs:schema elementFormDefault="qualified"
targetNamespace='http://docs.oasis-open.org/ws-sx/ws-trust/200512'
xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name='RequestSecurityToken'
type='wst:AbstractRequestSecurityTokenType' />
+ <xs:element name='RequestSecurityTokenResponse'
type='wst:AbstractRequestSecurityTokenType' />
+ <xs:complexType name='AbstractRequestSecurityTokenType' >
+ <xs:sequence>
+ <xs:any namespace='##any' processContents='lax'
minOccurs='0' maxOccurs='unbounded' />
+ </xs:sequence>
+ <xs:attribute name='Context' type='xs:anyURI'
use='optional' />
+ <xs:anyAttribute namespace='##other' processContents='lax'
/>
+ </xs:complexType>
+ <xs:element name='RequestSecurityTokenCollection'
type='wst:RequestSecurityTokenCollectionType' />
+ <xs:complexType name='RequestSecurityTokenCollectionType' >
+ <xs:sequence>
+ <xs:element name='RequestSecurityToken'
type='wst:AbstractRequestSecurityTokenType' minOccurs='2'
maxOccurs='unbounded'/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name='RequestSecurityTokenResponseCollection'
type='wst:RequestSecurityTokenResponseCollectionType' />
+ <xs:complexType name='RequestSecurityTokenResponseCollectionType'
>
+ <xs:sequence>
+ <xs:element ref='wst:RequestSecurityTokenResponse'
minOccurs='1' maxOccurs='unbounded' />
+ </xs:sequence>
+ <xs:anyAttribute namespace='##other' processContents='lax'
/>
+ </xs:complexType>
+ </xs:schema>
+ </wsdl:types>
+
+ <wsdl:message name="RequestSecurityTokenMsg">
+ <wsdl:part name="request"
element="wst:RequestSecurityToken" />
+ </wsdl:message>
+ <wsdl:message
name="RequestSecurityTokenResponseCollectionMsg">
+ <wsdl:part name="responseCollection"
+ element="wst:RequestSecurityTokenResponseCollection"/>
+ </wsdl:message>
+
+ <wsdl:portType name="SecureTokenService">
+ <wsdl:operation name="IssueToken">
+ <wsdl:input
wsap10:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/...
message="tns:RequestSecurityTokenMsg"/>
+ <wsdl:output
wsap10:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR...
message="tns:RequestSecurityTokenResponseCollectionMsg"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="STSBinding"
type="tns:SecureTokenService">
+ <wsp:PolicyReference URI="#UT_policy" />
+ <soap12:binding
transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="IssueToken">
+ <soap12:operation
soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Iss...
style="document"/>
+ <wsdl:input>
+ <wsp:PolicyReference URI="#Input_policy" />
+ <soap12:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <wsp:PolicyReference URI="#Output_policy" />
+ <soap12:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="PicketLinkSTS">
+ <wsdl:port name="PicketLinkSTSPort"
binding="tns:STSBinding">
+ <soap12:address
location="http://localhost:8080/picketlink-sts/PicketLinkSTS"/>
+ </wsdl:port>
+ </wsdl:service>
+
+ <wsp:Policy wsu:Id="UT_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <wsap10:UsingAddressing/>
+ <sp:SymmetricBinding
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <wsp:Policy>
+ <sp:ProtectionToken>
+ <wsp:Policy>
+ <sp:X509Token
+
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/...
+ <wsp:Policy>
+ <sp:RequireDerivedKeys />
+ <sp:RequireThumbprintReference />
+ <sp:WssX509V3Token10 />
+ </wsp:Policy>
+ </sp:X509Token>
+ </wsp:Policy>
+ </sp:ProtectionToken>
+ <sp:AlgorithmSuite>
+ <wsp:Policy>
+ <sp:Basic256 />
+ </wsp:Policy>
+ </sp:AlgorithmSuite>
+ <sp:Layout>
+ <wsp:Policy>
+ <sp:Lax />
+ </wsp:Policy>
+ </sp:Layout>
+ <sp:IncludeTimestamp />
+ <sp:EncryptSignature />
+ <sp:OnlySignEntireHeadersAndBody />
+ </wsp:Policy>
+ </sp:SymmetricBinding>
+ <sp:SignedSupportingTokens
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <wsp:Policy>
+ <sp:UsernameToken
+
sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/...
+ <wsp:Policy>
+ <sp:WssUsernameToken10 />
+ </wsp:Policy>
+ </sp:UsernameToken>
+ </wsp:Policy>
+ </sp:SignedSupportingTokens>
+ <sp:Wss11
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <wsp:Policy>
+ <sp:MustSupportRefKeyIdentifier />
+ <sp:MustSupportRefIssuerSerial />
+ <sp:MustSupportRefThumbprint />
+ <sp:MustSupportRefEncryptedKey />
+ </wsp:Policy>
+ </sp:Wss11>
+ <sp:Trust13
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <wsp:Policy>
+ <sp:MustSupportIssuedTokens />
+ <sp:RequireClientEntropy />
+ <sp:RequireServerEntropy />
+ </wsp:Policy>
+ </sp:Trust13>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+
+ <wsp:Policy wsu:Id="Input_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <sp:Body />
+ <sp:Header Name="To"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+
+ <wsp:Policy wsu:Id="Output_policy">
+ <wsp:ExactlyOne>
+ <wsp:All>
+ <sp:SignedParts
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <sp:Body />
+ <sp:Header Name="To"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="From"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="FaultTo"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="ReplyTo"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="MessageID"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="RelatesTo"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ <sp:Header Name="Action"
+
Namespace="http://www.w3.org/2005/08/addressing" />
+ </sp:SignedParts>
+ <sp:EncryptedParts
+
xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702&...
+ <sp:Body />
+ </sp:EncryptedParts>
+ </wsp:All>
+ </wsp:ExactlyOne>
+ </wsp:Policy>
+
+</wsdl:definitions></programlisting>
+ </informalexample>
+ <para>Differently from the Apache CXF STS example described above, the
PicketLink based STS gets its configuration from a picketlink-sts.xml descriptor which
must be added in WEB-INF into the deployment; please refer to the PicketLink documentation
for further information:</para>
+ <informalexample>
+ <programlisting><PicketLinkSTS
xmlns="urn:picketlink:identity-federation:config:1.0"
+ STSName="PicketLinkSTS" TokenTimeout="7200"
EncryptToken="false">
+ <KeyProvider
ClassName="org.picketlink.identity.federation.core.impl.KeyStoreKeyManager">
+ <Auth Key="KeyStoreURL" Value="stsstore.jks"/>
+ <Auth Key="KeyStorePass" Value="stsspass"/>
+ <Auth Key="SigningKeyAlias" Value="mystskey"/>
+ <Auth Key="SigningKeyPass" Value="stskpass"/>
+ <ValidatingAlias
Key="http://localhost:8080/jaxws-samples-wsse-policy-trust/SecurityService"
Value="myservicekey"/>
+ </KeyProvider>
+ <TokenProviders>
+ <TokenProvider
ProviderClass="org.picketlink.identity.federation.core.wstrust.plugins.saml.SAML11TokenProvider"
+
TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profi...
+ TokenElement="Assertion"
+ TokenElementNS="urn:oasis:names:tc:SAML:1.0:assertion"/>
+ <TokenProvider
ProviderClass="org.picketlink.identity.federation.core.wstrust.plugins.saml.SAML20TokenProvider"
+
TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profi...
+ TokenElement="Assertion"
+ TokenElementNS="urn:oasis:names:tc:SAML:2.0:assertion"/>
+ </TokenProviders>
+</PicketLinkSTS></programlisting>
+ </informalexample>
+ <para>Finally, the PicketLink alternative approach of course requires
different JBoss AS module dependencies to be declared in the MANIFEST.MF:</para>
+ <informalexample>
+ <programlisting>Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.8.2
+Created-By: 1.6.0_26-b03 (Sun Microsystems Inc.)
+Dependencies:
org.apache.ws.security,org.apache.cxf,org.picketlink</programlisting>
+ </informalexample>
+ <para>Here is how the PicketLink STS endpoint is packaged:</para>
+ <informalexample>
+ <programlisting>alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar
-tvf
./modules/testsuite/cxf-tests/target/test-libs/jaxws-samples-wsse-policy-trustPicketLink-sts.war
+ 0 Mon Sep 03 17:38:38 CEST 2012 META-INF/
+ 174 Mon Sep 03 17:38:36 CEST 2012 META-INF/MANIFEST.MF
+ 0 Mon Sep 03 17:38:38 CEST 2012 WEB-INF/
+ 0 Mon Sep 03 17:38:38 CEST 2012 WEB-INF/classes/
+ 0 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/classes/org/
+ 0 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/classes/org/jboss/
+ 0 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/classes/org/jboss/test/
+ 0 Mon Sep 03 16:35:52 CEST 2012 WEB-INF/classes/org/jboss/test/ws/
+ 0 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/classes/org/jboss/test/ws/jaxws/
+ 0 Mon Sep 03 16:35:52 CEST 2012 WEB-INF/classes/org/jboss/test/ws/jaxws/samples/
+ 0 Mon Sep 03 16:35:50 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/
+ 0 Mon Sep 03 16:35:50 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/
+ 0 Mon Sep 03 16:35:52 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/
+ 1686 Mon Sep 03 16:35:50 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/PicketLinkSTService.class
+ 1148 Mon Sep 03 16:35:52 CEST 2012
WEB-INF/classes/org/jboss/test/ws/jaxws/samples/wsse/policy/trust/STSCallbackHandler.class
+ 251 Mon Sep 03 17:38:34 CEST 2012 WEB-INF/jboss-web.xml
+ 0 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/wsdl/
+ 9070 Mon Sep 03 17:38:34 CEST 2012 WEB-INF/wsdl/PicketLinkSTS.wsdl
+ 1267 Mon Sep 03 17:38:34 CEST 2012 WEB-INF/classes/picketlink-sts.xml
+ 1054 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/classes/stsKeystore.properties
+ 3978 Mon Sep 03 16:35:50 CEST 2012 WEB-INF/classes/stsstore.jks</programlisting>
+ </informalexample>
+ </section>
+ </section>
+ </section>
<section id="sid-3866797">
<title>WS-Reliable Messaging</title>
@@ -1891,7 +3573,8 @@
using a Spring XML descriptor; here is an example:
</para>
<informalexample>
- <programlisting><beans
+ <programlisting>
+<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://cxf.apache.org/core"
@@ -1926,11 +3609,13 @@
</wsrm-mgr:reliableMessaging>
</cxf:features>
</cxf:bus>
-</beans</programlisting>
+</beans
+</programlisting>
</informalexample>
<para>The client needs to pick up the bus configuration such as
below:</para>
<informalexample>
- <programlisting>package org.jboss.test.ws.jaxws.samples.wsrm.client;
+ <programlisting>
+package org.jboss.test.ws.jaxws.samples.wsrm.client;
import java.net.URL;
import java.io.File;
@@ -1968,7 +3653,8 @@
bus.shutdown(true);
}
}
-}</programlisting>
+}
+</programlisting>
</informalexample>
</section>
</section>
@@ -2038,7 +3724,8 @@
</listitem>
</itemizedlist>
<informalexample>
- <programlisting><wsdl:definitions
name="HelloWorldService"
targetNamespace="http://org.jboss.ws/jaxws/cxf/jms"
+ <programlisting>
+<wsdl:definitions name="HelloWorldService"
targetNamespace="http://org.jboss.ws/jaxws/cxf/jms"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://org.jboss.ws/jaxws/cxf/jms"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
@@ -2063,7 +3750,8 @@
<wsdl:port binding="tns:HelloWorldServiceSoapBinding"
name="HelloWorldImplPort">
<soap:address location="jms:queue:testQueue"/> <!-- 1
-->
</wsdl:port>
-</wsdl:service></programlisting>
+</wsdl:service>
+</programlisting>
</informalexample>
<para>
Apache CXF takes care of setting up the JMS transport for endpoint
implementations whose
@@ -2165,6 +3853,14 @@
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorldService">
+
<soapjms:jndiConnectionFactoryName>java:jms/RemoteConnectionFactory</soapjms:jndiConnectionFactoryName>
+
<soapjms:jndiInitialContextFactory>org.jboss.naming.remote.client.InitialContextFactory</soapjms:jndiInitialContextFactory>
+ <soapjms:jndiURL>remote://myhost:4447</soapjms:jndiURL>
+ <wsdl:port binding="tns:HelloWorldServiceSoapBinding"
name="HelloWorldImplPort">
+ <soap:address location="jms:queue:testQueue"/>
+ </wsdl:port>
+ </wsdl:service>
+ <wsdl:service name="HelloWorldServiceLocal">
<soapjms:jndiConnectionFactoryName>java:/ConnectionFactory</soapjms:jndiConnectionFactoryName>
<wsdl:port binding="tns:HelloWorldServiceSoapBinding"
name="HelloWorldImplPort">
<soap:address location="jms:queue:testQueue"/>
@@ -2181,12 +3877,25 @@
that's available by default on JBoss Application Server 7
</para>
</important>
+ <para>
+ At the time of writing,
+ <emphasis
role="italics">java:/ConnectionFactory</emphasis>
+ is the default connection factory JNDI location on JBoss Application Server
7
+ </para>
+ <para>
+ For allowing remote JNDI lookup of the connection factory, a specific service
(
+ <code>HelloWorldService</code>
+ ) for remote clients is added to the WSDL. The
+ <emphasis
role="italics">java:jms/RemoteConnectionFactory</emphasis>
+ is the JNDI location of the same connection factory mentioned above, except
it's exposed for remote lookup. The
+ <code>soapjms:jndiInitialContextFactory</code>
+ and
+ <code>soap:jmsjndiURL</code>
+ complete the remote connection configuration, specifying the initial context
factory class to use and the JNDI registry address.
+ </para>
<important>
- <para>
- At the time of writing,
- <emphasis
role="italics">java:/ConnectionFactory</emphasis>
- is the default connection factory JNDI location on JBoss Application Server
7
- </para>
+ <para>Have a look at the application server domain for finding out the
configured connection factory JNDI locations.</para>
+ <para>Remote JNDI support is available starting from JBoss Application
Server 7.1.</para>
</important>
<para>The endpoint implementation is a basic JAX-WS POJO using
@WebService annotation to refer to the consumed contract:</para>
<informalexample>
@@ -2197,7 +3906,7 @@
@WebService
(
portName = "HelloWorldImplPort",
- serviceName = "HelloWorldService",
+ serviceName = "HelloWorldServiceLocal",
wsdlLocation = "META-INF/wsdl/HelloWorldService.wsdl",
endpointInterface = "org.jboss.test.ws.jaxws.cxf.jms.HelloWorld",
targetNamespace = "http://org.jboss.ws/jaxws/cxf/jms"
@@ -2210,6 +3919,13 @@
}
}</programlisting>
</informalexample>
+ <note>
+ <para>
+ The endpoint implementation references the
+ <code>HelloWorldServiceLocal</code>
+ wsdl service, so that the local JNDI connection factory location is used
for starting the endpoint on server side.
+ </para>
+ </note>
<para>
That's pretty much all. We just need to package the generated service
endpoint interface, the endpoint implementation and the WSDL file in a
<emphasis role="italics">jar</emphasis>
@@ -2258,17 +3974,73 @@
QName serviceName = new QName("http://org.jboss.ws/jaxws/cxf/jms",
"HelloWorldService");
Service service = Service.create(wsdlUrl, serviceName);
HelloWorld proxy = (HelloWorld) service.getPort(new
QName("http://org.jboss.ws/jaxws/cxf/jms", "HelloWorldImplPort"),
HelloWorld.class);
+ setupProxy(proxy);
proxy.echo("Hi");
}
finally
{
bus.shutdown(true);
-}</programlisting>
+}
+</programlisting>
</informalexample>
- <para></para>
<important>
<para>The WSDL location URL needs to be retrieved in a custom way,
depending on the client application. Given the endpoint is JMS only, there's no
automatically published WSDL contract.</para>
</important>
+ <para>in order for performing the remote invocation (which internally
goes through remote JNDI lookup of the connection factory), the calling user credentials
need to be set into the Apache CXF JMSConduit:</para>
+ <informalexample>
+ <programlisting>
+private void setupProxy(HelloWorld proxy) {
+ JMSConduit conduit = (JMSConduit)ClientProxy.getClient(proxy).getConduit();
+ JNDIConfiguration jndiConfig = conduit.getJmsConfig().getJndiConfig();
+ jndiConfig.setConnectionUserName("user");
+ jndiConfig.setConnectionPassword("password");
+ Properties props = conduit.getJmsConfig().getJndiTemplate().getEnvironment();
+ props.put(Context.SECURITY_PRINCIPAL, "user");
+ props.put(Context.SECURITY_CREDENTIALS, "password");
+}
+</programlisting>
+ </informalexample>
+ <important>
+ <para>
+ Have a look at the JBoss Application Server 7 domain and messaging
configuration for finding out the actual security requirements. At the time of writing, a
user with
+ <code>guest</code>
+ role is required and that's internally checked using the
+ <code>other</code>
+ security domain.
+ </para>
+ </important>
+ <para>Of course once the endpoint is exposed over JMS transport, any
plain JMS client can also be used to send messages to the webservice endpoint. You can
have a look at the SOAP over JMS spec details and code the client similarly
to</para>
+ <informalexample>
+ <programlisting>
+Properties env = new Properties();
+env.put(Context.INITIAL_CONTEXT_FACTORY,
"org.jboss.naming.remote.client.InitialContextFactory");
+env.put(Context.PROVIDER_URL, "remote://myhost:4447");
+env.put(Context.SECURITY_PRINCIPAL, "user");
+env.put(Context.SECURITY_CREDENTIALS, "password");
+InitialContext context = new InitialContext(env);
+QueueConnectionFactory connectionFactory =
(QueueConnectionFactory)context.lookup("jms/RemoteConnectionFactory");
+Queue reqQueue = (Queue)context.lookup("jms/queue/test");
+Queue resQueue = (Queue)context.lookup("jms/queue/test");
+QueueConnection con = connectionFactory.createQueueConnection("user",
"password");
+QueueSession session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
+QueueReceiver receiver = session.createReceiver(resQueue);
+ResponseListener responseListener = new ResponseListener(); //a custom response
listener...
+receiver.setMessageListener(responseListener);
+con.start();
+TextMessage message = session.createTextMessage(reqMessage);
+message.setJMSReplyTo(resQueue);
+
+//setup SOAP-over-JMS properties...
+message.setStringProperty("SOAPJMS_contentType", "text/xml");
+message.setStringProperty("SOAPJMS_requestURI",
"jms:queue:testQueue");
+
+QueueSender sender = session.createSender(reqQueue);
+sender.send(message);
+sender.close();
+
+...
+</programlisting>
+ </informalexample>
</section>
<section
id="sid-3866801_SOAPoverJMS-JMSandHTTPendpointsdeployment">
@@ -2353,7 +4125,9 @@
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorldService">
-
<soapjms:jndiConnectionFactoryName>java:/ConnectionFactory</soapjms:jndiConnectionFactoryName>
+
<soapjms:jndiConnectionFactoryName>java:jms/RemoteConnectionFactory</soapjms:jndiConnectionFactoryName>
+
<soapjms:jndiInitialContextFactory>org.jboss.naming.remote.client.InitialContextFactory</soapjms:jndiInitialContextFactory>
+
<soapjms:jndiURL>remote://localhost:4447</soapjms:jndiURL>
<wsdl:port binding="tns:HelloWorldServiceSoapBinding"
name="HelloWorldImplPort">
<soap:address location="jms:queue:testQueue"/>
</wsdl:port>
@@ -2361,6 +4135,11 @@
<soap:address
location="http://localhost:8080/jaxws-cxf-jms-http-deployment"/>
</wsdl:port>
</wsdl:service>
+ <wsdl:service name="HelloWorldServiceLocal">
+
<soapjms:jndiConnectionFactoryName>java:/ConnectionFactory</soapjms:jndiConnectionFactoryName>
+ <wsdl:port binding="tns:HelloWorldServiceSoapBinding"
name="HelloWorldImplPort">
+ <soap:address location="jms:queue:testQueue"/>
+ </wsdl:port>
</wsdl:definitions></programlisting>
</informalexample>
<para>
@@ -2376,7 +4155,7 @@
@WebService
(
portName = "HelloWorldImplPort",
- serviceName = "HelloWorldService",
+ serviceName = "HelloWorldServiceLocal",
wsdlLocation = "WEB-INF/wsdl/HelloWorldService.wsdl",
endpointInterface = "org.jboss.test.ws.jaxws.cxf.jms_http.HelloWorld",
targetNamespace = "http://org.jboss.ws/jaxws/cxf/jms"
@@ -2473,6 +4252,7 @@
//JMS test
HelloWorld proxy = (HelloWorld) service.getPort(new
QName("http://org.jboss.ws/jaxws/cxf/jms", "HelloWorldImplPort"),
HelloWorld.class);
+ setupProxy(proxy);
proxy.echo("Hi");
//HTTP test
HelloWorld httpProxy = (HelloWorld) service.getPort(new
QName("http://org.jboss.ws/jaxws/cxf/jms", "HttpHelloWorldImplPort"),
HelloWorld.class);