Modified: websites/production/cxf/content/docs/ws-security.html
==============================================================================
--- websites/production/cxf/content/docs/ws-security.html (original)
+++ websites/production/cxf/content/docs/ws-security.html Wed Sep 13 15:05:52
2017
@@ -32,9 +32,9 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
-<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
<script src='/resources/highlighter/scripts/shBrushBash.js'></script>
+<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -119,14 +119,14 @@ Apache CXF -- WS-Security
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><h1
id="WS-Security-WS-Security">WS-Security</h1><p>WS-Security provides means to
secure your services above and beyond transport level protocols such as HTTPS.
Through a number of standards such as XML-Encryption, and headers defined in
the WS-Security standard, it allows you to:</p><ul><li>Pass authentication
tokens between services</li><li>Encrypt messages or parts of
messages</li><li>Sign messages</li><li>Timestamp messages</li><li>Manage public
keys using <a shape="rect"
href="http://cxf.apache.org/docs/xml-key-management-service-xkms.html">XKMS</a></li></ul><p>CXF
relies on <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j">WSS4J</a> in large part to implement
WS-Security. Within your own services, WS-Security can be activated by using <a
shape="rect"
href="http://cxf.apache.org/docs/ws-securitypolicy.html">WS-SecurityPolicy</a>,
which provides a comprehensive and sophisticated validation of the security
properties of a received
message. A non-WS-SecurityPolicy approach is usually also possible by way of
CXF interceptors added to your service and/or client as detailed in this
article.</p><p>Please note that there are some incompatibilities between WSS4J
1.6.x (used by Apache CXF 2.6.x and 2.7.x) and 2.0.x (used by Apache CXF 3.0.x
and 3.1.x). The examples and links on this page mainly pertain to WSS4J 2.0.x
and hence CXF 3.0.x. For more information on the changes in WSS4J 2.0.x please
see the following <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/migration.html">migration page</a>.</p><h1
id="WS-Security-Overviewofencryptionandsigning">Overview of encryption and
signing</h1><p>WS-Security makes heavy use of public/private key cryptography.
To really understand how to configure WS-Security, it is helpful - if not
necessary - to understand these basics. The Wikipedia has an <a shape="rect"
class="external-link"
href="http://en.wikipedia.org/wiki/Public-key_cryptography" rel="nofollo
w">excellent entry</a> on this, but we'll try to summarize the relevant basics
here (This content is a modified version of the wikipedia content..)</p><p>With
public key cryptography, a user has a pair of public and private keys. These
are generated using a large prime number and a key function.<br clear="none">
<span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Public_key_making.svg/250px-Public_key_making.svg.png"
data-image-src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Public_key_making.svg/250px-Public_key_making.svg.png"></span></p><p>The
keys are related mathematically, but cannot be derived from one another. With
these keys we can encrypt messages. For example, if Bob wants to send a message
to Alice, he can encrypt a message using her public key. Alice can then decrypt
this message using her private key. Only Alice can decrypt this mes
sage as she is the only one with the private key.<br clear="none"> <span
class="confluence-embedded-file-wrapper"><img class="confluence-embedded-image
confluence-external-resource"
src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Public_key_encryption.svg/280px-Public_key_encryption.svg.png"
data-image-src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Public_key_encryption.svg/280px-Public_key_encryption.svg.png"></span></p><p>Messages
can also be signed. This allows you to ensure the authenticity of the message.
If Alice wants to send a message to Bob, and Bob wants to be sure that it is
from Alice, Alice can sign the message using her private key. Bob can then
verify that the message is from Alice by using her public key.<br clear="none">
<span class="confluence-embedded-file-wrapper"><img
class="confluence-embedded-image confluence-external-resource"
src="http://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Public_key_signing.svg/280px-Public_key_sig
ning.svg.png"
data-image-src="http://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Public_key_signing.svg/280px-Public_key_signing.svg.png"></span></p><h1
id="WS-Security-ConfiguringtheWSS4JInterceptors">Configuring the WSS4J
Interceptors</h1><p>To enable WS-Security within CXF for a server or a client,
you'll need to set up the WSS4J interceptors. You can either do this via the
API for standalone web services or via Spring XML configuration for
servlet-hosted ones. This section will provide an overview of how to do this,
and the following sections will go into more detail about configuring the
interceptors for specific security actions.</p><p>It is important to note
that:</p><ol><li>If you are using CXF 2.0.x, you must add the
SAAJ(In/Out)Interceptors if you're using WS-Security (This is done
automatically for you from CXF 2.1 onwards). These enable creation of a DOM
tree for each request/response. The support libraries for WS-Security require
DOM trees.</li><li>The web service
provider may not need both in and out WS-Security interceptors. For instance,
if you are just requiring signatures on incoming messages, the web service
provider will just need an incoming WSS4J interceptor and only the SOAP client
will need an outgoing one.</li></ol><h2
id="WS-Security-AddingtheinterceptorsviatheAPI">Adding the interceptors via the
API</h2><p>On the Server side, you'll want to add the interceptors to your CXF
Endpoint. If you're publishing your service using the JAX-WS APIs, you can get
your CXF endpoint like this:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import org.apache.cxf.endpoint.Endpoint;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.jaxws.EndpointImpl;
EndpointImpl jaxWsEndpoint = (EndpointImpl)
Endpoint.publish("http://host/service", myServiceImpl);
Endpoint cxfEndpoint = jaxWsEndpoint.getServer().getEndpoint();
</pre>
</div></div><p>If you've used the (JaxWs)ServerFactoryBean, you can simply
access it via the Server object:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import org.apache.cxf.endpoint.Endpoint;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import org.apache.cxf.endpoint.Endpoint;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.frontend.ServerFactoryBean;
@@ -136,7 +136,7 @@ Server server = factory.create();
Endpoint cxfEndpoint = server.getEndpoint();
</pre>
</div></div><p>On the client side, you can obtain a reference to the CXF
endpoint using the ClientProxy helper:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import org.apache.cxf.frontend.ClientProxy;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import org.apache.cxf.frontend.ClientProxy;
...
GreeterService gs = new GreeterService();
@@ -146,7 +146,7 @@ org.apache.cxf.endpoint.Client client =
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
</pre>
</div></div><p><span class="confluence-anchor-link"
id="WS-Security-addinterceptors"></span>Now you're ready to add the
interceptors:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor;
...
@@ -163,7 +163,7 @@ WSS4JOutInterceptor wssOut = new WSS4JOu
cxfEndpoint.getOutInterceptors().add(wssOut);
</pre>
</div></div><h1 id="WS-Security-SpringXMLConfiguration">Spring XML
Configuration</h1><p>If you're using Spring to build endpoints (e.g., web
services running on a servlet container such as Tomcat), you can easily
accomplish the above using your bean definitions instead.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><import resource="classpath:META-INF/cxf/cxf.xml"
/>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><import resource="classpath:META-INF/cxf/cxf.xml"
/>
<import resource="classpath*:META-INF/cxf/cxf-extension-*.xml" />
<jaxws:endpoint id="myService"
@@ -191,7 +191,7 @@ cxfEndpoint.getOutInterceptors().add(wss
</jaxws:endpoint>
</pre>
</div></div><p>The entry keys and values given in the constructor-arg element
above (action, signaturePropFile, etc.) map to the text strings in WSS4J's <a
shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/wss4j/dom/handler/WSHandlerConstants.html">WSHandlerConstants</a>
and <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/wss4j/dom/WSConstants.html">WSConstants</a>
classes for the corresponding WSHandlerConstants.XXXXX and WSConstants.XXXX
constants you see in the section below (also see the WSS4J configuration <a
shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/config.html">page</a>). So by viewing
WSHandlerConstants, for example, you can see that the
WSHandlerConstants.USERNAME_TOKEN value given below would need to be
"UsernameToken" instead when doing Spring configuration.</p><p>If you want to
avoid looking up the text keys for the WSHandlerConstants.XXXXX and
WSConstants.XXXX consta
nts, you can also use the Spring util namespace to reference static constants
in your Spring context as shown below.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><beans
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><beans
...
xmlns:util="http://www.springframework.org/schema/util"
...
@@ -219,7 +219,7 @@ cxfEndpoint.getOutInterceptors().add(wss
...
</pre>
</div></div><h2 id="WS-Security-AdditionalConfigurationOptions">Additional
Configuration Options</h2><p>While the CXF WSS4J interceptors support the
standard configuration properties available in WSHandlerConstants.XXXXX and
WSConstants.XXXX, CXF also provides access to some additional low level
configuration capabilities in WSS4J and some other security related
interceptors.</p><h3
id="WS-Security-ValidatingSignatureand/orEncryptionofMessageContents">Validating
Signature and/or Encryption of Message Contents</h3><p>As of CXF 2.2.8, the
CryptoCoverageChecker interceptor allows one to validate signature and
encryption coverage of message contents without migrating to a
WS-SecurityPolicy based configuration. The interceptor can support enforcement
of signature and encryption coverage at both the element and content level (be
aware that the combination of signature and content do not represent a valid
combination of coverage type and coverage scope). To configure this interceptor
using
the API, follow the example below.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import
org.apache.cxf.ws.security.wss4j.CryptoCoverageChecker;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import
org.apache.cxf.ws.security.wss4j.CryptoCoverageChecker;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageChecker.XPathExpression;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageScope;
import org.apache.cxf.ws.security.wss4j.CryptoCoverageUtil.CoverageType;
@@ -237,7 +237,7 @@ List<XPathExpression> xpaths = Arr
CryptoCoverageChecker checker = new CryptoCoverageChecker(prefixes, xpaths);
</pre>
</div></div><p>The interceptor can also be configured in Spring using the
conventional bean definition format.</p><p>After configuring the interceptor as
above, simply add the interceptor to your client or server interceptor chain as
shown previously with the WSS4J interceptors. Ensure that you include the
WSS4JInInterceptor in the chain or all requests will be denied if you enforce
any coverage XPaths.</p><p>The CryptoCoverageChecker is somewhat complex to set
up for the most common use-cases for signature verification and decryption, as
it involves adding XPath expressions and the corresponding prefix/namespace
pairs. In Apache CXF 2.4.9, 2.5.5 and 2.6.2, a new subclass of
CryptoCoverageChecker has been introduced. The DefaultCryptoCoverageChecker
provides an easy way to ensure that the SOAP Body is signed or encrypted, that
the Timestamp is signed, and that the WS-Addressing ReplyTo and FaultTo headers
are signed (if they are present in the message payload).</p><p>The default con
figuation is that the SOAP Body, (WSU) Timestamp and WS-Addressing ReplyTo and
FaultTo headers must be signed (if they exist in the message payload). This
provides an out-of-the-box way of preventing XML Signature wrapping attacks.
All that is required is that the DefaultCryptoCoverageChecker be added to the
in-interceptor chain. For example:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><jaxws:inInterceptors>
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><jaxws:inInterceptors>
<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
@@ -251,7 +251,7 @@ CryptoCoverageChecker checker = new Cryp
</jaxws:inInterceptors>
</pre>
</div></div><p>As of CXF 2.5.11, 2.6.8 and 2.7.5, it is possible to only check
that a received message meets cryptographic requirements via the
CryptoCoverageChecker if it is not a fault. This is useful in the scenario
where a client is using the CryptoCoverageChecker interceptor to verify
security requirements from a service response. In this scenario, you may want
to get the original service Fault rather than have the CryptoCoverageChecker
throw an exception if a Fault message from the service isn't secured. To enable
this behaviour, then set the "checkFaults" boolean property on
CryptoCoverageChecker to "false".</p><h3
id="WS-Security-CustomProcessors">Custom Processors</h3><p>As of CXF 2.0.10 and
2.1.4, you can specify custom WSS4J Processor configurations on the
WSS4JInInterceptor. To activate this configuration option, one provides a
non-WSS4J defined property, wss4j.processor.map, to the WSS4JInInterceptor as
shown in the following Spring example. The same configuration can b
e achieved through the API as well. The key value is an XML qualified name of
the WS-Security header element to process with the given processor
implementation. The entry values can be a String representing a class name of
the processor to instantiate, an Object implementing Processor, or null to
disable processing of the given WS-Security header element.</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean
class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
<constructor-arg>
<map>
...
@@ -275,7 +275,7 @@ CryptoCoverageChecker checker = new Cryp
</bean>
</pre>
</div></div><h3 id="WS-Security-CustomActions">Custom Actions</h3><p>As of CXF
2.2.6, you can specify custom WSS4J Action configurations on the
WSS4JOutInterceptor. To activate this configuration option, one provides a
non-WSS4J defined property, wss4j.action.map, to the WSS4JOutInterceptor as
shown in the following Spring example. The same configuration can be achieved
through the API as well. The key value is an integer representing the WSS4J
action identifier. The entry values can be a String representing a class name
of the action to instantiate or an Object implementing Action. This
configuration option allows you to override built-in action implementations or
add your own.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean
class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
<constructor-arg>
<map>
...
@@ -291,7 +291,7 @@ CryptoCoverageChecker checker = new Cryp
</bean>
</pre>
</div></div><p>For the case that adding new custom action, if the new key int
number is 12345, you must also specify new action name as string
"12345".</p><h1 id="WS-Security-ConfiguringWS-SecurityActions">Configuring
WS-Security Actions</h1><h2
id="WS-Security-UsernameTokenAuthentication">Username Token
Authentication</h2><p>WS-Security supports many ways of specifying tokens. One
of these is the UsernameToken header. It is a standard way to communicate a
username and password or password digest to another endpoint. Be sure to review
the OASIS <a shape="rect" class="external-link"
href="http://tinyurl.com/65n78j" rel="nofollow">UsernameToken Profile
Specification</a> for important security considerations when using
UsernameTokens.</p><p>If a nonce is present in a UsernameToken then it should
be cached by the message recipient to guard against replay attacks. This
behaviour is enabled by default starting with CXF 2.6.0. This functionality is
also available from Apache CXF 2.4.7 and
2.5.3 onwards, but is not enabled by default at all for
backwards-compatibility reasons. The following properties control nonce
caching:</p><ul><li>"ws-security.enable.nonce.cache" - Whether to cache
UsernameToken nonces. The default value (for CXF 2.6.0) is "true" for message
recipients, and "false" for message initiators. Set it to true to cache for
both cases. The default value for CXF 2.4.x and 2.5.x is false. See <a
shape="rect"
href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/ws/security/SecurityConstants.html#ENABLE_NONCE_CACHE">here</a>
for more information.</li><li>"ws-security.nonce.cache.instance" - This holds
a reference to a <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/wss4j/common/cache/ReplayCache.html">ReplayCache</a>
instance used to cache UsernameToken nonces. The default instance that is used
is the <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/wss4j/common/cache/EHCa
cheReplayCache.html">EHCacheReplayCache</a>.</li><li>"ws-security.cache.config.file"
- Set this property to point to a configuration file for the underlying
caching implementation. The default configuration file that is used is <a
shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/resources/cxf-ehcache.xml?view=markup">cxf-ehcache.xml</a>
in the cxf-rt-ws-security module.</li></ul><p>For the server side, you'll want
to set up the following properties on your WSS4JInInterceptor (see <a
shape="rect" href="ws-security.html">above</a> for code sample):</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">inProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">inProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
// Password type : plain text
inProps.put(WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT);
// for hashed password use:
@@ -301,7 +301,7 @@ inProps.put(WSHandlerConstants.PW_CALLBA
ServerPasswordHandler.class.getName());
</pre>
</div></div><p>The password callback class allows you to retrieve the password
for a given user so that WS-Security can determine if they're authorized. Here
is a small example:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import java.io.IOException;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
@@ -324,7 +324,7 @@ public class ServerPasswordCallback impl
}
</pre>
</div></div><p>Note that for up to and including CXF 2.3.x, the password
validation of the special case of a plain-text password (or any other yet
unknown password type) is delegated to the callback class. In that case, the
ServerPasswordCallback should be something like the following one:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">public class ServerPasswordCallback implements
CallbackHandler {
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class ServerPasswordCallback implements
CallbackHandler {
public void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException {
@@ -341,7 +341,7 @@ public class ServerPasswordCallback impl
}
</pre>
</div></div><p>For CXF 2.4 onwards, the callback handler supplies the password
for all cases, and the validation is done internally (but can be configured).
See <a shape="rect" class="external-link"
href="http://coheigea.blogspot.com/2011/02/usernametoken-processing-changes-in.html"
rel="nofollow">here</a> for more information.<br clear="none"> On the Client
side you'll want to configure the WSS4J outgoing properties:</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.USERNAME_TOKEN);
// Specify our username
outProps.put(WSHandlerConstants.USER, "joe");
// Password type : plain text
@@ -353,7 +353,7 @@ outProps.put(WSHandlerConstants.PW_CALLB
ClientPasswordHandler.class.getName());
</pre>
</div></div><p>Once again we're using a password callback, except this time
instead of specifying our password on the server side, we're specifying the
password we want sent with the message. This is so we don't have to store our
password in our configuration file.</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">import java.io.IOException;
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
@@ -373,47 +373,47 @@ public class ClientPasswordCallback impl
}
</pre>
</div></div><p>In the case of multiple users with different passwords, use the
<a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/wss4j/common/ext/WSPasswordCallback.html">WSPasswordCallback</a>'s
getIdentifier() method to obtain the username of the current SOAP
request.</p><p><a shape="rect" class="external-link"
href="http://depressedprogrammer.wordpress.com/2007/07/31/cxf-ws-security-using-jsr-181-interceptor-annotations-xfire-migration/"
rel="nofollow">Here is an example</a> of WS-Security implemented using
annotations for interceptors (uses UsernameToken).</p><h3
id="WS-Security-WS-SecurityUsernameTokenandCustomAuthentication">WS-Security
UsernameToken and Custom Authentication</h3><p>If needed, one may want to
configure a jaxws:endpoint with a "ws-security.validate.token" property set to
false and register a custom
org.apache.cxf.interceptor.security.AbstractUsernameTokenInInterceptor
implementation for using a WSS4J UsernameToken wrapped
in a CXF specific UsernameToken for the custom authentication and Subject
creation. The JAASLoginInterceptor will also recognize a CXF UsernameToken and
thus can be used instead of the custom
org.apache.cxf.interceptor.security.AbstractUsernameTokenInterceptor. (Prior to
CXF 2.4.0, use "ws-security.ut.no-callbacks" instead of
"ws-security.validate.token" with the value of true instead of false to
postpone the validation of the token.)</p><h2
id="WS-Security-UsingX.509Certificates">Using X.509 Certificates</h2><p>The
X.509 Certificate Token Profile (<a shape="rect" class="external-link"
href="http://www.oasis-open.org/committees/download.php/16785/wss-v1.1-spec-os-x509TokenProfile.pdf"
rel="nofollow">pdf</a>) provides another option for implementing WS-Security.
For the Signature and Encryption actions, you'll need to create a public &
private key for the entities involved. You can generate a self-signed key pair
for your development environment via the following steps. Keep in
mind these will not be signed by an external authority like Verisign, so are
inappropriate for production use.</p><p>1. Creating private key with given
alias and password like "myAlias"/"myAliasPassword" in keystore (protected by
password for<br clear="none"> security reasons)</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">keytool -genkey -alias myAlias -keypass myAliasPassword
-keystore \
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">keytool -genkey -alias myAlias -keypass myAliasPassword
-keystore \
privatestore.jks -storepass keyStorePassword -dname "cn=myAlias" -keyalg RSA
</pre>
</div></div><p>The alias is simply a way to identify the key pair. In this
instance we are using the RSA algorithm.</p><p>2. Self-sign our certificate (in
production environment this will be done by a company like Verisign).</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">keytool -selfcert -alias myAlias -keystore
privatestore.jks \
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">keytool -selfcert -alias myAlias -keystore
privatestore.jks \
-storepass keyStorePassword -keypass myAliasPassword
</pre>
</div></div><p>3. Export the public key from our private keystore to file
named key.rsa</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">keytool -export -alias myAlias -file key.rsa -keystore
privatestore.jks \
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">keytool -export -alias myAlias -file key.rsa -keystore
privatestore.jks \
-storepass keyStorePassword
</pre>
</div></div><p>4. Import the public key to new keystore:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">keytool -import -alias myAlias -file key.rsa -keystore
publicstore.jks \
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">keytool -import -alias myAlias -file key.rsa -keystore
publicstore.jks \
-storepass keyStorePassword
</pre>
</div></div><p>So now we have two keystores containing our keys - a public one
(publicstore.jks) and a private one (privatestore.jks). Both of them have
keystore password set to keyStorePass (this not recommended for production but
ok for development) and alias set to myAlias. The file key.rsa can removed from
filesystem, since it used only temporarily. Storing keys in keystores is
strongly advised because a keystore is protected by a password.</p><p>A more
detailed description of key generation can be found here:<br clear="none"> <a
shape="rect" class="external-link"
href="http://java.sun.com/javase/6/docs/technotes/tools/solaris/keytool.html"
rel="nofollow">http://java.sun.com/javase/6/docs/technotes/tools/solaris/keytool.html</a></p><p>How
to create a production certificate can be found here:<br clear="none"> <a
shape="rect" class="external-link"
href="http://support.globalsign.net/en/objectsign/java.cfm"
rel="nofollow">http://support.globalsign.net/en/objectsign/java.cfm</a></p>
<h3 id="WS-Security-Signing">Signing</h3><p>Signing a message is used to
validate to the recipient that the message could only have come from a certain
sender, and that the message was not altered in transit. It involves the sender
encrypting a digest (hash) of the message with its private key, and the
recipient decrypting the hash with the sender's public key, and recalculating
the digest of the message to make sure the message was not altered in transit
(i.e., that the digest values calculated by both the sender and recipient are
the same). For this process to occur you must ensure that the Client's public
key has been imported into the server's keystore using keytool.</p><p>On the
client side, our outgoing WS-Security properties will look like so (see <a
shape="rect" href="ws-security.html">above</a> for code sample):</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">outProps.put(WSHandlerConstants.ACTION, "Signature");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">outProps.put(WSHandlerConstants.ACTION, "Signature");
outProps.put(WSHandlerConstants.USER, "myAlias");
outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS,
ClientCallbackHandler.class.getName());
outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sign.properties");
</pre>
</div></div><p>The USER that is specified is the key alias for the client. The
password callback class is responsible for providing that key's
password.</p><div class="confluence-information-macro
confluence-information-macro-tip"><p class="title">Tip</p><span class="aui-icon
aui-icon-small aui-iconfont-approve
confluence-information-macro-icon"></span><div
class="confluence-information-macro-body"><p>For X.509 support you will
normally have multiple actions, e.g. Encryption with Signature. For these
cases, just space-separate the actions in the ACTION property as
follows:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">outProps.put(WSHandlerConstants.ACTION,
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">outProps.put(WSHandlerConstants.ACTION,
WSHandlerConstants.TIMESTAMP + " " +
WSHandlerConstants.SIGNATURE + " " +
WSHandlerConstants.ENCRYPT);
</pre>
</div></div><p>Alternatively, you may space-separate the string literals you
see above in the Spring configuration (e.g., "Signature
Encrypt")</p></div></div><p>Our client_sign.properties file contains several
settings to configure WSS4J:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">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=keyStorePassword
org.apache.ws.security.crypto.merlin.keystore.alias=myAlias
org.apache.ws.security.crypto.merlin.keystore.file=client_keystore.jks
</pre>
</div></div><p>On the server side, we need to configure our incoming WSS4J
interceptor to verify the signature using the Client's public key.</p><div
class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">inProps.put(WSHandlerConstants.ACTION, "Signature");
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">inProps.put(WSHandlerConstants.ACTION, "Signature");
inProps.put(WSHandlerConstants.SIG_PROP_FILE, "server.properties");
</pre>
</div></div><p>Our server_sign.properties file contains several settings to
configure WSS4J:</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">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=amex123
org.apache.ws.security.crypto.merlin.keystore.file=server_keystore.jks
Modified: websites/production/cxf/content/docs/ws-securitypolicy.html
==============================================================================
--- websites/production/cxf/content/docs/ws-securitypolicy.html (original)
+++ websites/production/cxf/content/docs/ws-securitypolicy.html Wed Sep 13
15:05:52 2017
@@ -32,8 +32,8 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -118,7 +118,7 @@ Apache CXF -- WS-SecurityPolicy
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><h1
id="WS-SecurityPolicy-WS-SecurityPolicy">WS-SecurityPolicy</h1><p>CXF 2.2
introduced support for using <a shape="rect" class="external-link"
href="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/v1.3/ws-securitypolicy.html"
rel="nofollow">WS-SecurityPolicy</a> to configure WSS4J instead of the custom
configuration documented on the <a shape="rect"
href="ws-security.html">WS-Security</a> page. However, all of the "background"
material on the <a shape="rect" href="ws-security.html">WS-Security</a> page
still applies and is important to know. WS-SecurityPolicy just provides an
easier and more standards based way to configure and control the security
requirements. With the security requirements documented in the WSDL as <a
shape="rect" href="ws-policy.html">WS-Policy</a> fragments, other tools such as
.NET can easily know how to configure themselves to inter-operate with CXF
services.</p><p>CXF supports WS-SecurityPolicy versions 1.1 and later. It does
not support WS-SecurityPolicy 1.0.</p><h3
id="WS-SecurityPolicy-Backwardscompatibilityconfigurationnote">Backwards
compatibility configuration note</h3><p>From Apache CXF 3.1.0, some of the
WS-Security based configuration tags have been changed to just start with
"security-". This is so that they can be shared with the <a shape="rect"
href="jax-rs-xml-security.html">JAX-RS XML Security</a> component. Apart from
the prefix change, the tags are exactly the same. Older "ws-security-" values
continue to be accepted in CXF 3.1.0. See the <a shape="rect"
href="security-configuration.html">Security Configuration</a> page for
information on the new shared configuration tags.</p><h3
id="WS-SecurityPolicy-EnablingWS-SecurityPolicy">Enabling
WS-SecurityPolicy</h3><p>In CXF 2.2, if the cxf-rt-ws-policy and
cxf-rt-ws-security modules are available on the classpath, the
WS-SecurityPolicy stuff is automatically enabled. Since the entire security
runtime is policy driven, the only requirement is t
hat the policy engine and security policies be available.</p><p>If you are
using the full "bundle" jar, all the security and policy stuff is already
included.</p><h3 id="WS-SecurityPolicy-Policydescription">Policy
description</h3><p>With WS-SecurityPolicy, the binding and/or operation in the
wsdl references a <a shape="rect" href="ws-policy.html">WS-Policy</a> fragment
that describes the basic security requirements for interacting with that
service. The <a shape="rect" class="external-link"
href="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/v1.3/ws-securitypolicy.html"
rel="nofollow">WS-SecurityPolicy specification</a> allows for specifying
things like asymmetric/symmetric keys, using transports (https) for encryption,
which parts/headers to encrypt or sign, whether to sign then encrypt or encrypt
then sign, whether to include timestamps, whether to use derived keys, etc...
Basically, it describes what actions are necessary to securely interact with
the service described in th
e WSDL.</p><p>However, the WS-SecurityPolicy fragment does not include
"everything" that is required for a runtime to be able to able to create the
messages. It does not describe things such as locations of key stores, user
names and passwords, etc... Those need to be configured in at runtime to
augment the WS-SecurityPolicy fragment.</p><h3
id="WS-SecurityPolicy-Configuringtheextraproperties">Configuring the extra
properties</h3><p>There are several extra properties that may need to be set to
provide the additional bits of information to the runtime. Note that you should
check that a particular property is supported in the version of CXF you are
using. First, see the <a shape="rect"
href="security-configuration.html">Security Configuration</a> page for
information on the configuration tags that are shared with the JAX-RS XML
Security component. Here are configuration tags that only apply to the
WS-SecurityPolicy layer, and hence all start with "ws-security" (as opposed to
the commo
n tags which now start with "security-").</p><p> </p><h4
id="WS-SecurityPolicy-BooleanWS-Securityconfigurationtags,e.g.thevalueshouldbe"true"or"false".">Boolean
WS-Security configuration tags, e.g. the value should be "true" or
"false".</h4><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>constant</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>default</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>definition</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.validate.token</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>true</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Whether to validate the password of a received
UsernameToken or not.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.username-token.always.encrypted</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>tr
ue</p></td><td colspan="1" rowspan="1" class="confluenceTd"><p>Whether to
always encrypt UsernameTokens that are defined as a SupportingToken. This
should not be set to false in a production environment, as it exposes the
password (or the digest of the password) on the wire.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.is-bsp-compliant</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>true</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Whether to ensure compliance with the Basic Security
Profile (BSP) 1.1 or not.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.self-sign-saml-assertion</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>false</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Whether to self-sign a SAML Assertion or
not. If this is set to true, then an enveloped signature will be generated when
the SAML Assertion is constructed. Only applies up to CXF 2.7.x.</
p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.enable.nonce.cache</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>(varies)</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Whether to cache UsernameToken nonces. See
<a shape="rect"
href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/ws/security/SecurityConstants.html#ENABLE_NONCE_CACHE">here</a>
for more information.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.enable.timestamp.cache</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>(varies)</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>Whether to cache Timestamp
Created Strings. See <a shape="rect"
href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/ws/security/SecurityConstants.html#ENABLE_TIMESTAMP_CACHE">here</a>
for more information.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.enable.saml.cache</td><td colspan="1" rowsp
an="1" class="confluenceTd">(varies)</td><td colspan="1" rowspan="1"
class="confluenceTd">Whether to cache SAML2 Token Identifiers, if the token
contains a "OneTimeUse" Condition.</td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.enable.streaming</td><td colspan="1"
rowspan="1" class="confluenceTd">false</td><td colspan="1" rowspan="1"
class="confluenceTd">Whether to enable streaming WS-Security.</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd">ws-security.return.security.error</td><td colspan="1"
rowspan="1" class="confluenceTd">false</td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Whether to return the security error message to the
client, and not one of the default error QNames.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd">ws-security.must-understand</td><td colspan="1"
rowspan="1" class="confluenceTd">true</td><td colspan="1" rowspan="1"
class="confluenceTd"><p>Set this to "false" in order to remove the SOAP mustU
nderstand header from security headers generated based on a
WS-SecurityPolicy.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.store.bytes.in.attachment</td><td colspan="1"
rowspan="1" class="confluenceTd">(varies)</td><td colspan="1" rowspan="1"
class="confluenceTd"><strong>CXF 3.1.3/3.0.6</strong> Whether to store bytes
(CipherData or BinarySecurityToken) in an attachment if MTOM is enabled. True
by default in CXF 3.1.x, false for CXF 3.0.x.</td></tr><tr><td colspan="1"
rowspan="1" class="confluenceTd">ws-security.use.str.transform</td><td
colspan="1" rowspan="1" class="confluenceTd">true</td><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>CXF 3.1.5/3.0.8 </strong>Whether to
use the STR (Security Token Reference) Transform when (externally) signing a
SAML Token. The default is true.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.add.inclusive.prefixes</td><td colspan="1"
rowspan="1" class="confluenceTd">true<
/td><td colspan="1" rowspan="1" class="confluenceTd"><strong>CXF
3.1.7</strong> Whether to add an InclusiveNamespaces PrefixList as a
CanonicalizationMethod child when generating Signatures using
WSConstants.C14N_EXCL_OMIT_COMMENTS.</td></tr></tbody></table></div><h4
id="WS-SecurityPolicy-Non-booleanWS-SecurityConfigurationparameters">Non-boolean
WS-Security Configuration parameters</h4><div class="table-wrap"><table
class="confluenceTable"><tbody><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.timestamp.timeToLive</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>The time in seconds to append
to the Creation value of an incoming Timestamp to determine whether to accept
the Timestamp as valid or not. The default value is 300 seconds (5
minutes).</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.timestamp.futureTimeToLive</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>The time in seconds in the
future with
in which the Created time of an incoming Timestamp is valid. The default value
is "60". See <a shape="rect"
href="http://cxf.apache.org/javadoc/latest/org/apache/cxf/ws/security/SecurityConstants.html#TIMESTAMP_FUTURE_TTL">here</a>
for more information.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.spnego.client.action</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>The <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/spnego/SpnegoClientAction.html">SpnegoClientAction</a>
implementation to use for SPNEGO. This allows the user to plug in a different
implementation to obtain a service ticket.</p></td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p>ws-security.nonce.cache.instance</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>This holds a reference to a <a
shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/cache/R
eplayCache.html">ReplayCache</a> instance used to cache UsernameToken nonces.
The default instance that is used is the <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/cache/EHCacheReplayCache.java?view=markup">EHCacheReplayCache</a>.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.timestamp.cache.instance</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>This holds a reference to a <a
shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/cache/ReplayCache.html">ReplayCache</a>
instance used to cache Timestamp Created Strings. The default instance that is
used is the <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/cache/EHCacheReplayCache.java?view=markup">EHCacheReplayCache</a>.</p></td></tr><tr><td
colspan="1" rowspa
n="1" class="confluenceTd">ws-security.saml.cache.instance</td><td colspan="1"
rowspan="1" class="confluenceTd">This holds a reference to a <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/cache/ReplayCache.html">ReplayCache</a>
instance used to cache SAML2 Token Identifiers, when the token has a
"OneTimeUse" Condition. The default instance that is used is the <a
shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/cache/EHCacheReplayCache.java?view=markup">EHCacheReplayCache</a>.</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.cache.config.file</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>Set this property to point to a
configuration file for the underlying caching implementation. The default
configuration file that is used is <a shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/cxf/tr
unk/rt/ws/security/src/main/resources/cxf-ehcache.xml?view=markup">cxf-ehcache.xml</a>
in the cxf-rt-ws-security module.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>org.apache.cxf.ws.security.tokenstore.TokenStore</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>The <a shape="rect"
class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/TokenStore.java?view=markup">TokenStore</a>
instance to use to cache security tokens. By default this uses the <a
shape="rect" class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/EHCacheTokenStore.java?view=markup">EHCacheTokenStore</a>
if EhCache is available. Otherwise it uses the <a shape="rect"
class="external-link"
href="http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/tokenstore/MemoryTokenStore.java?view=m
arkup">MemoryTokenStore</a>.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.cache.identifier</td><td colspan="1"
rowspan="1" class="confluenceTd">The Cache Identifier to use with the
TokenStore. CXF uses the following key to retrieve a token store:
"org.apache.cxf.ws.security.tokenstore.TokenStore-<identifier>". This key
can be used to configure service-specific cache configuration. If the
identifier does not match, then it falls back to a cache configuration with key
"org.apache.cxf.ws.security.tokenstore.TokenStore". The default
"<identifier>" is the QName of the service in question.</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.role.classifier</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>If one of the WSS4J Validators returns a
JAAS Subject from Validation, then the WSS4JInInterceptor will attempt to
create a SecurityContext based on this Subject. If this value is not specified,
then it tries
to get roles using the DefaultSecurityContext in cxf-rt-core. Otherwise it
uses this value in combination with the SUBJECT_ROLE_CLASSIFIER_TYPE to get the
roles from the Subject.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.role.classifier.type</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>If one of the WSS4J Validators
returns a JAAS Subject from Validation, then the WSS4JInInterceptor will
attempt to create a SecurityContext based on this Subject. Currently accepted
values are "prefix" or "classname". Must be used in conjunction with the
SUBJECT_ROLE_CLASSIFIER. The default value is "prefix".</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.asymmetric.signature.algorithm</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>This configuration tag
overrides the default Asymmetric Signature algorithm (RSA-SHA1) for use in
WS-SecurityPolicy, as the WS-SecurityPolicy specification does not allow t
he use of other algorithms at present.</p></td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd">ws-security.symmetric.signature.algorithm</td><td
colspan="1" rowspan="1" class="confluenceTd">This configuration tag overrides
the default Symmetric Signature algorithm (HMAC-SHA1) for use in
WS-SecurityPolicy, as the WS-SecurityPolicy specification does not allow the
use of other algorithms at present.</td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.password.encryptor.instance</td><td
colspan="1" rowspan="1" class="confluenceTd"><p>A PasswordEncryptor instance,
which is used to encrypt or decrypt passwords in the Merlin Crypto
implementation</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.delegated.credential</td><td colspan="1"
rowspan="1" class="confluenceTd">A delegated credential to use for WS-Security.
Currently only a Kerberos GSSCredential Object is supported. This is used to
retrieve a service ticket instead of usi
ng the client credentials.</td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.security.token.lifetime</td><td colspan="1"
rowspan="1" class="confluenceTd"><p><strong>CXF 3.1.9</strong> The security
token lifetime value (in milliseconds). The default is "300000" (5
minutes).</p></td></tr></tbody></table></div><h4
id="WS-SecurityPolicy-Validatorimplementationsforvalidatingreceivedsecuritytokens">Validator
implementations for validating received security tokens</h4><div
class="table-wrap"><table class="confluenceTable"><tbody><tr><td colspan="1"
rowspan="1" class="confluenceTd"><p>ws-security.ut.validator</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to
use to validate UsernameTokens. The default value is the <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/UsernameTokenValidator.html">UsernameTokenValidator</a>.</p></td></tr><tr><td
colspan="1" rowspan="1" cl
ass="confluenceTd"><p>ws-security.saml1.validator</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to use to
validate SAML 1.1 Tokens. The default value is the <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/SamlAssertionValidator.html">SamlAssertionValidator</a>.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.saml2.validator</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to use to
validate SAML 2.0 Tokens. The default value is the <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/SamlAssertionValidator.html">SamlAssertionValidator</a>.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.timestamp.validator</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to use to
validate Times
tamps. The default value is the <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/TimestampValidator.html">TimestampValidator</a>.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.signature.validator</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to use to
validate trust in credentials used in Signature verification. The default value
is the <a shape="rect" class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/SignatureTrustValidator.html">SignatureTrustValidator</a>.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.bst.validator</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to use to
validate BinarySecurityTokens. The default value is the <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/secur
ity/validate/NoOpValidator.html">NoOpValidator</a>.</p></td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.sct.validator</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The WSS4J Validator instance to use to
validate SecurityContextTokens. The default value is the <a shape="rect"
class="external-link"
href="http://ws.apache.org/wss4j/apidocs/org/apache/ws/security/validate/NoOpValidator.html">NoOpValidator</a>.</p></td></tr></tbody></table></div><h4
id="WS-SecurityPolicy-KerberosConfigurationtags">Kerberos Configuration
tags</h4><div class="table-wrap"><table class="confluenceTable"><tbody><tr><td
colspan="1" rowspan="1" class="confluenceTd"><p>constant</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>default</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>definition</p></td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd">ws-security.kerberos.request.credential.delegation</td><td
colspan="1" rowspan="1" class="co
nfluenceTd">false</td><td colspan="1" rowspan="1" class="confluenceTd">Whether
to request credential delegation or not in the KerberosClient.</td></tr><tr><td
colspan="1" rowspan="1"
class="confluenceTd">ws-security.kerberos.use.credential.delegation</td><td
colspan="1" rowspan="1" class="confluenceTd">false</td><td colspan="1"
rowspan="1" class="confluenceTd">Whether to use credential delegation or not in
the KerberosClient.</td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd">ws-security.kerberos.is.username.in.servicename.form</td><td
colspan="1" rowspan="1" class="confluenceTd">false</td><td colspan="1"
rowspan="1" class="confluenceTd">Whether the Kerberos username is in
servicename form or not.</td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.kerberos.client</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>n/a</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>A reference to the <a shape="rect"
class="external-link" href=
"http://svn.apache.org/viewvc/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/kerberos/KerberosClient.java?view=markup">KerberosClient</a>
class used to obtain a service ticket.</p></td></tr><tr><td colspan="1"
rowspan="1"
class="confluenceTd"><p>ws-security.kerberos.jaas.context</p></td><td
colspan="1" rowspan="1" class="confluenceTd"><p>n/a</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>The JAAS Context name to use for
Kerberos.</p></td></tr><tr><td colspan="1" rowspan="1"
class="confluenceTd"><p>ws-security.kerberos.spn</p></td><td colspan="1"
rowspan="1" class="confluenceTd"><p>n/a</p></td><td colspan="1" rowspan="1"
class="confluenceTd"><p>The Kerberos Service Provider Name (spn) to
use.</p></td></tr></tbody></table></div><h4
id="WS-SecurityPolicy-ConfiguringviaSpring">Configuring via Spring</h4><p>The
properties are easily configured as client or endpoint properties--use the
former for the SOAP client, the latter for the web service provider.</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><beans
xmlns="http://www.springframework.org/schema/beans"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
@@ -143,7 +143,7 @@ Apache CXF -- WS-SecurityPolicy
</beans>
</pre>
</div></div><p>For the jaxws:client's <em>name</em> attribute above, use the
namespace of the WSDL along with the <em>name</em> attribute of the desired
wsdl:port element under the WSDL's service section. (See <a shape="rect"
class="external-link" href="http://tinyurl.com/yatskw4" rel="nofollow">here</a>
and <a shape="rect" class="external-link" href="http://tinyurl.com/y9e7rjf"
rel="nofollow">here</a> for an example.)</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><beans
xmlns="http://www.springframework.org/schema/beans"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
@@ -173,7 +173,7 @@ Apache CXF -- WS-SecurityPolicy
</beans>
</pre>
</div></div><p>See this <a shape="rect" class="external-link"
href="http://www.jroller.com/gmazza/entry/cxf_x509_profile" rel="nofollow">blog
entry</a> for a more end-to-end example of using WS-SecurityPolicy with X.509
keys.</p><h4 id="WS-SecurityPolicy-ConfiguringviaAPI's">Configuring via
API's</h4><p>Configuring the properties for the client just involves setting
the properties in the client's RequestContext:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">Map<String, Object> ctx =
((BindingProvider)port).getRequestContext();
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">Map<String, Object> ctx =
((BindingProvider)port).getRequestContext();
ctx.put("security.encryption.properties", properties);
port.echoString("hello");
</pre>
Modified: websites/production/cxf/content/docs/ws-trust.html
==============================================================================
--- websites/production/cxf/content/docs/ws-trust.html (original)
+++ websites/production/cxf/content/docs/ws-trust.html Wed Sep 13 15:05:52 2017
@@ -32,8 +32,8 @@
<link type="text/css" rel="stylesheet"
href="/resources/highlighter/styles/shThemeCXF.css">
<script src='/resources/highlighter/scripts/shCore.js'></script>
-<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script src='/resources/highlighter/scripts/shBrushXml.js'></script>
+<script src='/resources/highlighter/scripts/shBrushJava.js'></script>
<script>
SyntaxHighlighter.defaults['toolbar'] = false;
SyntaxHighlighter.all();
@@ -118,7 +118,7 @@ Apache CXF -- WS-Trust
<!-- Content -->
<div class="wiki-content">
<div id="ConfluenceContent"><h1
id="WS-Trust-WS-Trust">WS-Trust</h1><p>WS-Trust support in CXF builds upon the
<a shape="rect" href="ws-securitypolicy.html">WS-SecurityPolicy</a>
implementation to handle the IssuedToken policy assertions that could be found
in the WS-SecurityPolicy fragment.</p><p><strong>Note:</strong> Because the
WS-IssuedToken support builds on the WS-SecurityPolicy support, this is
currently only available to "wsdl first" projects.</p><p>WS-Trust extends the
WS-Security specification to allow issuing, renewing, and validation of
security tokens. A lot of what WS-Trust does centers around the use of a
"Security Token Service", or STS. The STS is contacted to obtain security
tokens that are used to create messages to talk to the services. The primary
use of the STS is to acquire SAML tokens used to talk to the service. Why is
this interesting?</p><p>When using "straight" WS-Security, the client and
server need to have keys exchanged in advance. If the client and s
erver are both in the same security domain, that isn't usually a problem, but
for larger, complex applications spanning multiple domains, that can be a
burden. Also, if multiple services require the same security credentials,
updating all the services when those credentials change can by a major
operation.</p><p>WS-Trust solves this by using security tokens that are
obtained from a trusted Security Token Service. A client authenticates itself
with the STS based on policies and requirements defined by the STS. The STS
then provides a security token (example: 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.</p><p>When the WS-SecurityPolicy
runtime in CXF encounters an IssuedToken assertion in the policy, the runtime
requires an instance of org.apache.cxf.ws.security.trust.STSClient to talk to
the STS to obtain the required token. Since the STSClient is a
WS-SecurityPolicy client
, it will need configuration items to be able to create its secure SOAP
messages to talk to the STS.</p><h2 id="WS-Trust-GeneralConfiguration">General
Configuration</h2><p>There are several ways to configure the
STSClient:</p><p><strong>Direct configuration of an STSClient bean in the
properties:</strong><br clear="none"> In this scenario, a STSClient object is
created directly as a property of the client object. The wsdlLocation,
service/endpoint names, etc... are all configured in line for that
client.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><jaxws:client
name="{http://cxf.apache.org/}MyService" createdFromAPI="true">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><jaxws:client
name="{http://cxf.apache.org/}MyService" createdFromAPI="true">
<jaxws:properties>
<entry key="ws-security.sts.client">
<!-- direct STSClient config and creation -->
@@ -149,20 +149,20 @@ Apache CXF -- WS-Trust
</jaxws:client>
</pre>
</div></div><p>The above example shows a configuration where the STS uses the
UsernameToken profile to validate the client. It is assumed the keystore
identified within clientKeystore.properties contains both the private key of
the client and the public key (identified above as mystskey) of the STS; if
not, create separate property files for the signature properties and the
encryption properties, pointing to the keystore and truststore
respectively.</p><p>Remember the jaxws:client createdFromAPI attribute needs to
be set to true (as shown above) if you created the client programmatically via
the CXF API's--i.e., Endpoint.publish() or Service.getPort().</p><p>This also
works for "code first" cases as you can do:</p><div class="code panel pdl"
style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">STSClient sts = new STSClient(...);
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">STSClient sts = new STSClient(...);
sts.setXXXX(....)
.....
((BindingProvider)port).getRequestContext().put("ws-security.sts.client", sts);
</pre>
</div></div><p>Sample clientKeystore.properties format:</p><div class="code
panel pdl" style="border-width: 1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">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=KeystorePasswordHere
org.apache.ws.security.crypto.merlin.keystore.alias=ClientKeyAlias
org.apache.ws.security.crypto.merlin.keystore.file=NameOfKeystore.jks
</pre>
</div></div><p><strong>Indirect configuration based on endpoint
name:</strong><br clear="none"> If the runtime does not find a STSClient bean
configured directly on the client, it checks the configuration for a STSClient
bean with the name of the endpoint appended with ".sts-client". For example, if
the endpoint name for your client is "{<a shape="rect"
href="http://cxf.apache.org/">http://cxf.apache.org/</a>}TestEndpoint", then it
can be configured as:</p><div class="code panel pdl" style="border-width:
1px;"><div class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean
name="{http://cxf.apache.org/}TestEndpoint.sts-client"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean
name="{http://cxf.apache.org/}TestEndpoint.sts-client"
class="org.apache.cxf.ws.security.trust.STSClient" abstract="true">
<property name="wsdlLocation" value="WSDL/wsdl/trust.wsdl"/>
<property name="serviceName"
@@ -181,7 +181,7 @@ org.apache.ws.security.crypto.merlin.key
</bean>
</pre>
</div></div><p>This properties configured in this example demonstrate STS
validation of the client using the X.509 token profile. The abstract="true"
setting for the bean defers creation of the STSClient object until it is
actually needed. When that occurs, the CXF runtime will instantiate a new
STSClient using the values configured for this bean.</p><p><strong>Default
configuration:</strong><br clear="none"> If an STSClient is not found from the
above methods, it then tries to find one configured like the indirect, but with
the name "default.sts-client". This can be used to configure sts-clients for
multiple services.</p><h2 id="WS-Trust-WS-Trust1.4Support">WS-Trust 1.4
Support</h2><p>CXF supports some of the new functionality defined in the
WS-Trust 1.4 specification. The currently supported features are listed
below.</p><h3 id="WS-Trust-ActAs">ActAs</h3><p>The ActAs capability allows an
initiator to request a security token that allows it to act as if it were
somebody else. This
capability becomes important in composite services where intermediate services
make additional requests on-behalf of the true initiator. In this scenario, the
relying party (the final destination of an indirect service request) may
require information about the true origin of the request. The ActAs capability
allows an intermediary to request a token that can convey this
information.</p><p>The content of the ActAs element to be sent in the STS
RequestSecurityToken call can be set in one of two ways:</p><ol><li>By
specifying a value for the JAX-WS property SecurityConstants.STS_TOKEN_ACT_AS
("ws-security.sts.token.act-as")</li><li>By specifying a value for the
STSClient.actAs property.</li></ol><p>For either case, the value can be one of
the following:</p><ul><li>A String</li><li>A DOM Element</li><li>A
CallbackHandler object to use to obtain the token</li></ul><p>For example, the
following code fragment demonstrates how to use an interceptor to dynamically
set the content of the Act
As element in the STS RST, by specifying a value for
SecurityConstants.STS_TOKEN_ACT_AS. Note that this interceptor is applied to
the secured client, the initiator, and not to the STSClient's interceptor
chain.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">public class ActAsOutInterceptor extends
AbstractPhaseInterceptor<Message> {
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">public class ActAsOutInterceptor extends
AbstractPhaseInterceptor<Message> {
ActAsOutInterceptor () {
// This can be in any stage before the WS-SP interceptors
@@ -196,7 +196,7 @@ org.apache.ws.security.crypto.merlin.key
}
</pre>
</div></div><p>Alternatively, the ActAs content may be set directly on the STS
as shown below.</p><div class="code panel pdl" style="border-width: 1px;"><div
class="codeContent panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;"><bean
name="{http://cxf.apache.org/}TestEndpoint.sts-client"
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;"><bean
name="{http://cxf.apache.org/}TestEndpoint.sts-client"
class="org.apache.cxf.ws.security.trust.STSClient" abstract="true">
<property name="wsdlLocation" value="WSDL/wsdl/trust.wsdl"/>
<property name="serviceName"
Modified: websites/production/cxf/content/docs/wsaconfiguration.html
==============================================================================
--- websites/production/cxf/content/docs/wsaconfiguration.html (original)
+++ websites/production/cxf/content/docs/wsaconfiguration.html Wed Sep 13
15:05:52 2017
@@ -136,7 +136,7 @@ Apache CXF -- WSAConfiguration
<p>For example, to apply this feature to a JAX-WS server endpoint:</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">
<beans ... xmlns:wsa="http://cxf.apache.org/ws/addressing" ...>
<jaxws:endpoint ...>
<jaxws:features>
@@ -153,7 +153,7 @@ Apache CXF -- WSAConfiguration
On a global level, i.e. applicable to all client and server endpoints, this
can be done as in the example below (see also <a shape="rect"
href="bus-configuration.html">Bus Configuration</a>). Note that, as
allowDuplicates and usingAddressingAdvisory are actually properties of the
MAPAggregator interceptor, they can also be set using Spring syntax.</p>
<div class="code panel pdl" style="border-width: 1px;"><div class="codeContent
panelContent pdl">
-<pre class="brush: bash; gutter: false; theme: Confluence"
style="font-size:12px;">
+<pre class="brush: java; gutter: false; theme: Default"
style="font-size:12px;">
<bean id="mapAggregator"
class="org.apache.cxf.ws.addressing.MAPAggregator">
<property name="allowDuplicates" value="false"/>
</bean>