[[security]]
= Securing Your Web services with Spring-WS

This chapter explains how to add WS-Security aspects to your Web services.
We focus on the three different areas of WS-Security:

* *Authentication*: This is the process of determining whether a principal is who they claim to be.
In this context, a "principal" generally means a user, device or some other system that can perform an action in your application.
* *Digital signatures*: The digital signature of a message is a piece of information based on both the document and the signer's private key.
It is created through the use of a hash function and a private signing function (encrypting with the signer's private key).
* *Encryption and Decryption*: Encryption is the process of transforming data into a form that is impossible to read without the appropriate key.
It is mainly used to keep information hidden from anyone for whom it is not intended.
Decryption is the reverse of encryption.
It is the process of transforming encrypted data back into a readable form.

These three areas are implemented by using the `XwsSecurityInterceptor` or `Wss4jSecurityInterceptor`, which we describe in <<security-xws-security-interceptor>> and <<security-wss4j-security-interceptor>>, respectively.

[NOTE]
====
WS-Security (especially encryption and signing) requires substantial amounts of memory and can decrease performance.
If performance is important to you, you might want to consider not using WS-Security or using HTTP-based security.
====

[[security-xws-security-interceptor]]
== `XwsSecurityInterceptor`

The `XwsSecurityInterceptor` is an `EndpointInterceptor` (see <<server-endpoint-interceptor>>) that is based on SUN's XML and Web Services Security package (XWSS).
This WS-Security implementation is part of the Java Web Services Developer Pack (https://www.oracle.com/java/technologies/java-archive-jwsdp-downloads.html[Java WSDP]).

Like any other endpoint interceptor, it is defined in the endpoint mapping (see <<server-endpoint-mapping>>).
This means that you can be selective about adding WS-Security support.
Some endpoint mappings require it, while others do not.

[NOTE]
====
XWSS requires a SUN SAAJ reference implementation.
The WSS4J interceptor does not have these requirements (see <<security-wss4j-security-interceptor>>).
====

The `XwsSecurityInterceptor` requires a security policy file to operate.
This XML file tells the interceptor what security aspects to require from incoming SOAP messages and what aspects to add to outgoing messages.
The basic format of the policy file is explained in the following sections, but a more in-depth tutorial https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp564887[is available].
You can set the policy with the `policyConfiguration` property, which requires a Spring resource.
The policy file can contain multiple elements -- for example, require a username token on incoming messages and sign all outgoing messages.
It contains a `SecurityConfiguration` element (not a `JAXRPCSecurity` element) as its root.

Additionally, the security interceptor requires one or more `CallbackHandler` instances to operate.
These handlers are used to retrieve certificates, private keys, validate user credentials, and so on.
Spring-WS offers handlers for most common security concerns -- for example, authenticating against a Spring Security authentication manager and signing outgoing messages based on a X509 certificate.
The following sections indicate what callback handler to use for which security concern.
You can set the callback handlers by using the `callbackHandler` or `callbackHandlers` property.

The following example that shows how to wire up the `XwsSecurityInterceptor`:

====
[source,xml]
----
<beans>
    <bean id="wsSecurityInterceptor"
        class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
        <property name="policyConfiguration" value="classpath:securityPolicy.xml"/>
        <property name="callbackHandlers">
            <list>
                <ref bean="certificateHandler"/>
                <ref bean="authenticationHandler"/>
            </list>
        </property>
    </bean>
    ...
</beans>
----
====

This interceptor is configured by using the `securityPolicy.xml` file on the classpath.
It uses two callback handlers that are defined later in the file.

[[keystore]]
=== Keystores

For most cryptographic operations, you an use the standard `java.security.KeyStore` objects.
These operations include certificate verification, message signing, signature verification, and encryption.
They exclude username and time-stamp verification.
This section aims to give you some background knowledge on keystores and the Java tools that you can use to store keys and certificates in a keystore file.
This information is mostly not related to Spring-WS but to the general cryptographic features of Java.

The `java.security.KeyStore` class represents a storage facility for cryptographic keys and certificates.
It can contain three different sort of elements:

* *Private Keys*: These keys are used for self-authentication.
The private key is accompanied by a certificate chain for the corresponding public key.
Within the field of WS-Security, this accounts for message signing and message decryption.
* *Symmetric Keys*: Symmetric (or secret) keys are also used for message encryption and decryption -- the difference being that both sides (sender and recipient) share the same secret key.
* *Trusted certificates*: These X509 certificates are called a "trusted certificate" because the keystore owner trusts that the public key in the certificates does indeed belong to the owner of the certificate.
Within WS-Security, these certificates are used for certificate validation, signature verification, and encryption.

==== Using `keytool`

The `keytool` program, a key and certificate management utility, is supplied with your Java Virtual Machine.
You can use this tool to create new keystores, add new private keys and certificates to them, and so on.
It is beyond the scope of this document to provide a full reference of the `keytool` command, check the https://docs.oracle.com/en/java/javase/17/docs/specs/man/keytool.html[standard reference] or invoke `keytool -help` on the command line.

==== Using `KeyStoreFactoryBean`

To easily load a keystore by using Spring configuration, you can use the `KeyStoreFactoryBean`.
It has a resource location property, which you can set to point to the path of the keystore to load.
A password may be given to check the integrity of the keystore data.
If a password is not given, integrity checking is not performed.
The following listing configures a `KeyStoreFactoryBean`:

====
[source,xml]
----
<bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
    <property name="password" value="password"/>
    <property name="location" value="classpath:org/springframework/ws/soap/security/xwss/test-keystore.jks"/>
</bean>
----
====

WARNING: If you do not specify the location property, a new, empty keystore is created, which is most likely not what you want.

[[security-key-store-callback-handler]]
==== KeyStoreCallbackHandler

To use the keystores within a `XwsSecurityInterceptor`, you need to define a `KeyStoreCallbackHandler`.
This callback has three properties with type `keystore`: (`keyStore`,`trustStore`, and `symmetricStore`).
The exact stores used by the handler depend on the cryptographic operations that are to be performed by this handler.
For private key operation, the `keyStore` is used.
For symmetric key operations, the `symmetricStore` is used.
For determining trust relationships, the `trustStore` is used.
The following table indicates this:

[cols="2", options="header"]
|===
| Cryptographic operation
| Keystore used

| Certificate validation
| First `keyStore`, then `trustStore`

| Decryption based on private key
| `keyStore`

| Decryption based on symmetric key
| `symmetricStore`

| Encryption based on public key certificate
| `trustStore`

| Encryption based on symmetric key
| `symmetricStore`

| Signing
| `keyStore`

| Signature verification
| `trustStore`
|===

Additionally, the `KeyStoreCallbackHandler` has a `privateKeyPassword` property, which should be set to unlock the private keys contained in the`keyStore`.

If the `symmetricStore` is not set, it defaults to the `keyStore`.
If the key or trust store is not set, the callback handler uses the standard Java mechanism to load or create it.
See {spring-ws-api}/soap/security/wss4j2/callback/KeyStoreCallbackHandler.html[`KeyStoreCallbackHandler`] for more details.

For instance, if you want to use the `KeyStoreCallbackHandler` to validate incoming certificates or signatures, you can use a trust store:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="trustStore" ref="trustStore"/>
    </bean>

    <bean id="trustStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:truststore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

If you want to use it to decrypt incoming certificates or sign outgoing messages, you can use a key store:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="keyStore" ref="keyStore"/>
        <property name="privateKeyPassword" value="changeit"/>
    </bean>

    <bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:keystore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

The following sections indicate where the `KeyStoreCallbackHandler` can be used and which properties to set for particular cryptographic operations.

=== Authentication

As stated in the <<security,introduction to this chapter>>, authentication is the task of determining whether a principal is who they claim to be.
Within WS-Security, authentication can take two forms: using a username and password token (using either a plain text password or a password digest) or using a X509 certificate.

==== Plain Text Username Authentication

The simplest form of username authentication uses plain text passwords.
In this scenario, the SOAP message contains a `UsernameToken` element, which itself contains a `Username` element and a `Password` element which contains the plain text password.
Plain text authentication can be compared to the basic authentication provided by HTTP servers.

[WARNING]
====
Plain text passwords are not very secure.
Therefore, you should always add additional security measures to your transport layer if you use them (using HTTPS instead of plain HTTP, for instance).
====

To require that every incoming message contains a `UsernameToken` with a plain text password, the security policy file should contain a `RequireUsernameToken` element, with the `passwordDigestRequired` attribute set to `false`.
Fore more details, check the https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp567459[official reference] of possible child elements.
The following listing shows how to include a `RequireUsernameToken` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    ...
    <xwss:RequireUsernameToken passwordDigestRequired="false" nonceRequired="false"/>
    ...
</xwss:SecurityConfiguration>
----
====

If the username token is not present, the `XwsSecurityInterceptor` returns a SOAP fault to the sender.
If it is present, it fires a `PasswordValidationCallback` with a `PlainTextPasswordRequest` to the registered handlers.
Within Spring-WS, there are three classes that handle this particular callback:

* <<security-simple-password-validation-callback-handler,`SimplePasswordValidationCallbackHandler`>>
* <<using-springplaintextpasswordvalidationcallbackhandler,`SpringPlainTextPasswordValidationCallbackHandler`>>
* <<using-jaasplaintextpasswordvalidationcallbackhandler,`JaasPlainTextPasswordValidationCallbackHandler`>>

[[security-simple-password-validation-callback-handler]]
===== Using `SimplePasswordValidationCallbackHandler`

The simplest password validation handler is the `SimplePasswordValidationCallbackHandler`.
This handler validates passwords against an in-memory `Properties` object, which you can specify by using the `users` property:

====
[source,xml]
----
<bean id="passwordValidationHandler"
    class="org.springframework.ws.soap.security.xwss.callback.SimplePasswordValidationCallbackHandler">
    <property name="users">
        <props>
            <prop key="Bert">Ernie</prop>
        </props>
    </property>
</bean>
----
====

In this case, we are allowing only the user, "Bert", to log in by using the password, "Ernie".

[[using-springplaintextpasswordvalidationcallbackhandler]]
===== Using `SpringPlainTextPasswordValidationCallbackHandler`

The `SpringPlainTextPasswordValidationCallbackHandler` uses https://spring.io/projects/spring-security[Spring Security] to authenticate users.
It is beyond the scope of this document to describe Spring Security, but it is a full-fledged security framework.
You can read more about it in the https://docs.spring.io/spring-security/reference[Spring Security reference documentation].

The `SpringPlainTextPasswordValidationCallbackHandler` requires an `AuthenticationManager` to operate.
It uses this manager to authenticate against a `UsernamePasswordAuthenticationToken` that it creates.
If authentication is successful, the token is stored in the `SecurityContextHolder`.
You can set the authentication manager by using the `authenticationManager` property:

====
[source,xml]
----
<beans>
  <bean id="springSecurityHandler"
      class="org.springframework.ws.soap.security.xwss.callback.SpringPlainTextPasswordValidationCallbackHandler">
    <property name="authenticationManager" ref="authenticationManager"/>
  </bean>

  <bean id="authenticationManager" class=" org.springframework.security.authentication.ProviderManager">
      <constructor-arg>
          <bean class="org.springframework.security.providers.dao.DaoAuthenticationProvider">
              <property name="userDetailsService" ref="userDetailsService"/>
          </bean>
      </constructor-arg>
  </bean>

  <bean id="userDetailsService" class="com.mycompany.app.dao.UserDetailService" />
  ...
</beans>
----
====

[[using-jaasplaintextpasswordvalidationcallbackhandler]]
===== Using `JaasPlainTextPasswordValidationCallbackHandler`

The `JaasPlainTextPasswordValidationCallbackHandler` is based on the standard https://www.oracle.com/java/technologies/javase/javase-tech-security.html[Java Authentication and Authorization Service].
It is beyond the scope of this document to provide a full introduction into JAAS, but https://docs.oracle.com/javase/8/docs/technotes/guides/security/jaas/tutorials/index.html[tutorials] are available.

The `JaasPlainTextPasswordValidationCallbackHandler` requires only a `loginContextName` to operate.
It creates a new JAAS `LoginContext` by using this name and handles the standard JAAS `NameCallback` and `PasswordCallback` by using the username and password provided in the SOAP message.
This means that this callback handler integrates with any JAAS `LoginModule` that fires these callbacks during the `login()` phase, which is standard behavior.

You can wire up a `JaasPlainTextPasswordValidationCallbackHandler` as follows:

====
[source,xml]
----
<bean id="jaasValidationHandler"
    class="org.springframework.ws.soap.security.xwss.callback.jaas.JaasPlainTextPasswordValidationCallbackHandler">
    <property name="loginContextName" value="MyLoginModule" />
</bean>
----
====

In this case, the callback handler uses the `LoginContext` named `MyLoginModule`.
This module should be defined in your `jaas.config` file, as explained in the http://www.javaworld.com/javaworld/jw-09-2002/jw-0913-jaas.html[tutorial mentioned earlier].

==== Digest Username Authentication

When using password digests, the SOAP message also contains a `UsernameToken` element, which itself contains a `Username` element and a `Password` element.
The difference is that the password is not sent as plain text, but as a digest.
The recipient compares this digest to the digest he calculated from the known password of the user, and, if they are the same, the user is authenticated.
This method is comparable to the digest authentication provided by HTTP servers.

To require that every incoming message contains a `UsernameToken` element with a password digest, the security policy file should contain a `RequireUsernameToken` element, with the `passwordDigestRequired` attribute set to `true`.
Additionally, the `nonceRequired` attribute should be set to `true`.
For more details, check the http://java.sun.com/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp567459[official reference] of possible child elements.
The following listing shows how to define a `RequireUsernameToken` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    ...
    <xwss:RequireUsernameToken passwordDigestRequired="true" nonceRequired="true"/>
    ...
</xwss:SecurityConfiguration>
----
====

If the username token is not present, the `XwsSecurityInterceptor` returns a SOAP fault to the sender.
If it is present, it fires a `PasswordValidationCallback` with a `DigestPasswordRequest` to the registered handlers.
Within Spring-WS, two classes handle this particular callback: `SimplePasswordValidationCallbackHandler` and `SpringDigestPasswordValidationCallbackHandler`.

===== Using `SimplePasswordValidationCallbackHandler`

The `SimplePasswordValidationCallbackHandler` can handle both plain text passwords as well as password digests.
It is described in <<security-simple-password-validation-callback-handler>>.

===== Using `SpringDigestPasswordValidationCallbackHandler`

The `SpringDigestPasswordValidationCallbackHandler` requires a Spring Security `UserDetailService` to operate.
It uses this service to retrieve the password of the user specified in the token.
The digest of the password contained in this details object is then compared with the digest in the message.
If they are equal, the user has successfully authenticated, and a `UsernamePasswordAuthenticationToken` is stored in the `SecurityContextHolder`.
You can set the service by using the `userDetailsService` property.
Additionally, you can set a `userCache` property, to cache loaded user details.
The following example shows how to do so:

====
[source,xml]
----
<beans>
    <bean class="org.springframework.ws.soap.security.xwss.callback.SpringDigestPasswordValidationCallbackHandler">
        <property name="userDetailsService" ref="userDetailsService"/>
    </bean>

    <bean id="userDetailsService" class="com.mycompany.app.dao.UserDetailService" />
    ...
</beans>
----
====

[[security-certificate-authentication]]
==== Certificate Authentication

A more secure way of authentication uses X509 certificates.
In this scenario, the SOAP message contains a `BinarySecurityToken`, which contains a Base 64-encoded version of a X509 certificate.
The certificate is used by the recipient to authenticate.
The certificate stored in the message is also used to sign the message (see <<security-verifying-signatures>>).

To make sure that all incoming SOAP messages carry a`BinarySecurityToken`, the security policy file should contain a `RequireSignature` element.
This element can further carry other elements, which are covered in <<security-verifying-signatures>>.
For more details, check the http://java.sun.com/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565769[official reference] of possible child elements.
The following listing shows how to define a `RequireSignature` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    ...
    <xwss:RequireSignature requireTimestamp="false">
    ...
</xwss:SecurityConfiguration>
----
====

When a message arrives that carries no certificate, the `XwsSecurityInterceptor` returns a SOAP fault to the sender.
If it is present, it fires a `CertificateValidationCallback`.
Two handlers within Spring-WS handle this callback for authentication purposes:

* <<using-keystorecallbackhandler,`KeyStoreCallbackHandler`>>
* <<using-springcertificatevalidationcallbackhandler,`SpringCertificateValidationCallbackHandler`>>

[NOTE]
=====
In most cases, certificate authentication should be preceded by certificate validation, since you want to authenticate against only valid certificates.
Invalid certificates, such as certificates for which the expiration date has passed or which are not in your store of trusted certificates, should be ignored.

In Spring-WS terms, this means that the `SpringCertificateValidationCallbackHandler` or `JaasCertificateValidationCallbackHandler` should be preceded by `KeyStoreCallbackHandler`.
This can be accomplished by setting the order of the `callbackHandlers` property in the configuration of the `XwsSecurityInterceptor`:

====
[source,xml]
----
<bean id="wsSecurityInterceptor"
    class="org.springframework.ws.soap.security.xwss.XwsSecurityInterceptor">
    <property name="policyConfiguration" value="classpath:securityPolicy.xml"/>
    <property name="callbackHandlers">
        <list>
            <ref bean="keyStoreHandler"/>
            <ref bean="springSecurityHandler"/>
        </list>
    </property>
</bean>
----
====

Using this setup, the interceptor first determines if the certificate in the message is valid by using the keystore and then authenticating against it.
=====

[[using-keystorecallbackhandler]]
===== Using `KeyStoreCallbackHandler`

The `KeyStoreCallbackHandler` uses a standard Java keystore to validate certificates.
This certificate validation process consists of the following steps:

. The handler checks whether the certificate is in the private `keyStore`.
If it is, it is valid.
. If the certificate is not in the private keystore, the handler checks whether the current date and time are within the validity period given in the certificate.
If they are not, the certificate is invalid.
If it is, it continues with the final step.
. A certification path for the certificate is created.
This basically means that the handler determines whether the certificate has been issued by any of the certificate authorities in the `trustStore`.
If a certification path can be built successfully, the certificate is valid.
Otherwise, the certificate is not valid.

To use the `KeyStoreCallbackHandler` for certificate validation purposes, you most likely need to set only the `trustStore` property:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="trustStore" ref="trustStore"/>
    </bean>

    <bean id="trustStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:truststore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

Using the setup shown in the preceding example, the certificate that is to be validated must be in the trust store itself or the trust store must contain a certificate authority that issued the certificate.

[[using-springcertificatevalidationcallbackhandler]]
===== Using `SpringCertificateValidationCallbackHandler`

The `SpringCertificateValidationCallbackHandler` requires an Spring Security `AuthenticationManager` to operate.
It uses this manager to authenticate against a `X509AuthenticationToken` that it creates.
The configured authentication manager is expected to supply a provider that can handle this token (usually an instance of `X509AuthenticationProvider`).
If authentication is successful, the token is  stored in the `SecurityContextHolder`.
You can set the authentication manager by using the `authenticationManager` property:

====
[source,xml]
----
<beans>
    <bean id="springSecurityCertificateHandler"
        class="org.springframework.ws.soap.security.xwss.callback.SpringCertificateValidationCallbackHandler">
        <property name="authenticationManager" ref="authenticationManager"/>
    </bean>

    <bean id="authenticationManager"
        class="org.springframework.security.providers.ProviderManager">
        <property name="providers">
            <bean class="org.springframework.ws.soap.security.x509.X509AuthenticationProvider">
                <property name="x509AuthoritiesPopulator">
                    <bean class="org.springframework.ws.soap.security.x509.populator.DaoX509AuthoritiesPopulator">
                        <property name="userDetailsService" ref="userDetailsService"/>
                    </bean>
                </property>
            </bean>
        </property>
    </bean>

  <bean id="userDetailsService" class="com.mycompany.app.dao.UserDetailService" />
  ...
</beans>
----
====

In this case, we use a custom user details service to obtain authentication details based on the certificate.
See the http://www.springframework.org/security[Spring Security reference documentation] for more information about authentication against X509 certificates.

=== Digital Signatures

The digital signature of a message is a piece of information based on both the document and the signer's private key.
Two main tasks are related to signatures in WS-Security: verifying signatures and signing messages.

[[security-verifying-signatures]]
==== Verifying Signatures

As with <<security-certificate-authentication,certificate-based authentication>>, a signed message contains a `BinarySecurityToken`, which contains the certificate used to sign the message.
Additionally, it contains a `SignedInfo` block, which indicates what part of the message was signed.

To make sure that all incoming SOAP messages carry a `BinarySecurityToken`, the security policy file should contain a `RequireSignature` element.
It can also contain a `SignatureTarget` element, which specifies the target message part that was expected to be signed and various other sub-elements.
You can also define the private key alias to use, whether to use a symmetric instead of a private key, and many other properties.
For more details, check the https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565769[official reference] of possible child elements.
The following listing configures a `RequireSignature` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    <xwss:RequireSignature requireTimestamp="false"/>
</xwss:SecurityConfiguration>
----
====

If the signature is not present, the `XwsSecurityInterceptor` returns a SOAP fault to the sender.
If it is present, it fires a `SignatureVerificationKeyCallback` to the registered handlers.
Within Spring-WS, one class handles this particular callback: `KeyStoreCallbackHandler`.

===== Using `KeyStoreCallbackHandler`

As described in <<security-key-store-callback-handler>>, `KeyStoreCallbackHandler` uses a `java.security.KeyStore` for handling various cryptographic callbacks, including signature verification.
For signature verification, the handler uses the `trustStore` property:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="trustStore" ref="trustStore"/>
    </bean>

    <bean id="trustStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:org/springframework/ws/soap/security/xwss/test-truststore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

==== Signing Messages

When signing a message, the `XwsSecurityInterceptor` adds the `BinarySecurityToken` to the message.
It also adds a `SignedInfo` block, which indicates what part of the message was signed.

To sign all outgoing SOAP messages, the security policy file should contain a `Sign` element.
It can also contain a `SignatureTarget` element, which specifies the target message part that was expected to be signed and various other sub-elements.
You can also define the private key alias to use, whether to use a symmetric instead of a private key, and many other properties.
For more details, check the https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565497[official reference] of possible child elements.
The following example includes a `Sign` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
	<xwss:Sign includeTimestamp="false" />
</xwss:SecurityConfiguration>
----
====

The `XwsSecurityInterceptor` fires a `SignatureKeyCallback` to the registered handlers.
Within Spring-WS, the `KeyStoreCallbackHandler` class handles this particular callback.

===== Using `KeyStoreCallbackHandler`

As described in <<security-key-store-callback-handler>>, the `KeyStoreCallbackHandler` uses a `java.security.KeyStore` to handle various cryptographic callbacks, including signing messages.
For adding signatures, the handler uses the `keyStore` property.
Additionally, you must set the `privateKeyPassword` property to unlock the private key used for signing.
The following example uses a `KeyStoreCallbackHandler`:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="keyStore" ref="keyStore"/>
        <property name="privateKeyPassword" value="changeit"/>
    </bean>

    <bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:keystore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

=== Decryption and Encryption

When encrypting, the message is transformed into a form that can be read only with the appropriate key.
The message can be decrypted to reveal the original, readable message.

==== Decryption

To decrypt incoming SOAP messages, the security policy file should contain a `RequireEncryption` element.
This element can further carry a `EncryptionTarget` element that indicates which part of the message should be encrypted and a `SymmetricKey` to indicate that a shared secret instead of the regular private key should be used to decrypt the message.
For more details, check the https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565951[official reference ] of the other elements.
The following example uses a `RequireEncryption` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    <xwss:RequireEncryption />
</xwss:SecurityConfiguration>
----
====

If an incoming message is not encrypted, the `XwsSecurityInterceptor` returns a SOAP fault to the sender.
If it is present, it fires a `DecryptionKeyCallback` to the registered handlers.
Within Spring-WS, the `KeyStoreCallbackHandler` class handles this particular callback.

===== Using `KeyStoreCallbackHandler`

As described in <<security-key-store-callback-handler>>, the `KeyStoreCallbackHandler` uses a `java.security.KeyStore` to handle various cryptographic callbacks, including decryption.
For decryption, the handler uses the `keyStore` property.
Additionally, you must set the `privateKeyPassword` property to unlock the private key used for decryption.
For decryption based on symmetric keys, it uses the `symmetricStore`.
The following example uses `KeyStoreCallbackHandler`:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="keyStore" ref="keyStore"/>
        <property name="privateKeyPassword" value="changeit"/>
    </bean>

    <bean id="keyStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:keystore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

==== Encryption

To encrypt outgoing SOAP messages, the security policy file should contain an `Encrypt` element.
This element can further carry a `EncryptionTarget` element that indicates which part of the message should be encrypted and a `SymmetricKey` to indicate that a shared secret instead of the regular public key should be used to encrypt the message.
For more details, check the https://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.6/tutorial/doc/XWS-SecurityIntro4.html#wp565951[official reference] of the other elements.
The following example uses an `Encrypt` element:

====
[source,xml]
----
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config">
    <xwss:Encrypt />
</xwss:SecurityConfiguration>
----
====

The `XwsSecurityInterceptor` fires an `EncryptionKeyCallback` to the registered handlers to retrieve the encryption information.
Within Spring-WS, the `KeyStoreCallbackHandler` class handles this particular callback.

===== Using `KeyStoreCallbackHandler`

As described in <<security-key-store-callback-handler>>, the `KeyStoreCallbackHandler` uses a `java.security.KeyStore` to handle various cryptographic callbacks, including encryption.
For encryption based on public keys, the handler uses the `trustStore` property.
For encryption based on symmetric keys, it uses `symmetricStore`.
The following example uses `KeyStoreCallbackHandler`:

====
[source,xml]
----
<beans>
    <bean id="keyStoreHandler" class="org.springframework.ws.soap.security.xwss.callback.KeyStoreCallbackHandler">
        <property name="trustStore" ref="trustStore"/>
    </bean>

    <bean id="trustStore" class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
        <property name="location" value="classpath:truststore.jks"/>
        <property name="password" value="changeit"/>
    </bean>
</beans>
----
====

[[security-xws-exception-handling]]
=== Security Exception Handling

When a securement or validation action fails, the `XwsSecurityInterceptor` throws a `WsSecuritySecurementException` or `WsSecurityValidationException` respectively.
These exceptions bypass the <<server-endpoint-exception-resolver,standard exception handling mechanism>> but are handled by the interceptor itself.

`WsSecuritySecurementException` exceptions are handled by the `handleSecurementException` method of the `XwsSecurityInterceptor`.
By default, this method logs an error and stops further processing of the message.

Similarly, `WsSecurityValidationException` exceptions are handled by the `handleValidationException` method of the `XwsSecurityInterceptor`.
By default, this method creates a SOAP 1.1 Client or SOAP 1.2 sender fault and sends that back as a response.

NOTE: Both `handleSecurementException` and `handleValidationException` are protected methods, which you can override to change their default behavior.

[[security-wss4j-security-interceptor]]
== Using `Wss4jSecurityInterceptor`

The `Wss4jSecurityInterceptor` is an `EndpointInterceptor` (see <<server-endpoint-interceptor>>) that is based on https://ws.apache.org/wss4j/[Apache's WSS4J].

WSS4J implements the following standards:

* OASIS Web Services Security: SOAP Message Security 1.0 Standard 200401, March 2004.
* Username Token profile V1.0.
* X.509 Token Profile V1.0.

This interceptor supports messages created by the `AxiomSoapMessageFactory` and the `SaajSoapMessageFactory`.

=== Configuring `Wss4jSecurityInterceptor`

WSS4J uses no external configuration file.
The interceptor is entirely configured by properties.
The validation and securement actions invoked by this interceptor are specified via `validationActions` and `securementActions` properties, respectively.
Actions are passed as a space-separated strings.
The following listing shows an example configuration:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="validationActions" value="UsernameToken Encrypt"/>
    ...
    <property name="securementActions" value="Encrypt"/>
    ...
</bean>
----
====

The following table shows the available validation actions:

[cols="2", options="header"]
|===
| Validation action
| Description

| `UsernameToken`
| Validates username token

| `Timestamp`
| Validates the timestamp

| `Encrypt`
| Decrypts the message

| `Signature`
| Validates the signature

| `NoSecurity`
| No action performed
|===

The following table shows the available securement actions:

[cols="2", options="header"]
|===
| Securement action
| Description

| `UsernameToken`
| Adds a username token

| `UsernameTokenSignature`
| Adds a username token and a signature username token secret key

| `Timestamp`
| Adds a timestamp

| `Encrypt`
| Encrypts the response

| `Signature`
| Signs the response

| `NoSecurity`
| No action performed
|===

The order of the actions is significant and is enforced by the interceptor.
If its security actions were performed in a different order than the one specified by `validationActions`, the interceptor rejects an incoming SOAP message.

=== Handling Digital Certificates

For cryptographic operations that require interaction with a keystore or certificate handling (signature, encryption, and decryption operations), WSS4J requires an instance of `org.apache.ws.security.components.crypto.Crypto`.

`Crypto` instances can be obtained from WSS4J's `CryptoFactory` or more conveniently with the Spring-WS `CryptoFactoryBean`.

==== CryptoFactoryBean

Spring-WS provides a convenient factory bean, `CryptoFactoryBean`, that constructs and configures `Crypto` instances through strongly typed properties (preferred) or through a `Properties` object.

By default, `CryptoFactoryBean` returns instances of `org.apache.ws.security.components.crypto.Merlin`.
You can change this by setting the `cryptoProvider` property (or its equivalent `org.apache.ws.security.crypto.provider` string property).

The following example configuration uses `CryptoFactoryBean`:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
    <property name="keyStorePassword" value="mypassword"/>
    <property name="keyStoreLocation" value="file:/path_to_keystore/keystore.jks"/>
</bean>
----
====

=== Authentication

This section addresses how to do authentication with `Wss4jSecurityInterceptor`.

==== Validating Username Token

Spring-WS provides a set of callback handlers to integrate with Spring Security.
Additionally, a simple callback handler, `SimplePasswordValidationCallbackHandler`, is provided to configure users and passwords with an in-memory `Properties` object.

Callback handlers are configured through the `validationCallbackHandler` of the `Wss4jSecurityInterceptor` property.

===== Using `SimplePasswordValidationCallbackHandler`

`SimplePasswordValidationCallbackHandler` validates plain text and digest username tokens against an in-memory `Properties` object.
You can configure it as follows:

====
[source,xml]
----
<bean id="callbackHandler"
    class="org.springframework.ws.soap.security.wss4j.callback.SimplePasswordValidationCallbackHandler">
    <property name="users">
        <props>
            <prop key="Bert">Ernie</prop>
        </props>
    </property>
</bean>
----
====

===== Using `SpringSecurityPasswordValidationCallbackHandler`

The `SpringSecurityPasswordValidationCallbackHandler` validates plain text and digest passwords by using a Spring Security `UserDetailService` to operate.
It uses this service to retrieve the password (or a digest of the password) of the user specified in the token.
The password (or a digest of the password) contained in this details object is then compared with the digest in the message.
If they are equal, the user has successfully authenticated, and a `UsernamePasswordAuthenticationToken` is stored in the `SecurityContextHolder`.
You can set the service by using the `userDetailsService`.
Additionally, you can set a `userCache` property, to cache loaded user details, as follows:

====
[source,xml]
----
<beans>
    <bean class="org.springframework.ws.soap.security.wss4j.callback.SpringDigestPasswordValidationCallbackHandler">
        <property name="userDetailsService" ref="userDetailsService"/>
    </bean>

    <bean id="userDetailsService" class="com.mycompany.app.dao.UserDetailService" />
    ...
</beans>
----
====

==== Adding Username Token

Adding a username token to an outgoing message is as simple as adding `UsernameToken` to the `securementActions` property of the `Wss4jSecurityInterceptor` and specifying `securementUsername` and `securementPassword`.

The password type can be set by setting the `securementPasswordType` property.
Possible values are `PasswordText` for plain text passwords or `PasswordDigest` for digest passwords, which is the default.

The following example generates a username token with a digest password:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="securementActions" value="UsernameToken"/>
    <property name="securementUsername" value="Ernie"/>
    <property name="securementPassword" value="Bert"/>
</bean>
----
====

If the plain text password type is chosen, it is possible to instruct the interceptor to add `Nonce` and `Created` elements by setting the `securementUsernameTokenElements` property.
The value must be a list that contains the desired elements' names separated by spaces (case-sensitive).

The following example generates a username token with a plain text password, a `Nonce`, and a `Created` element:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="securementActions" value="UsernameToken"/>
    <property name="securementUsername" value="Ernie"/>
    <property name="securementPassword" value="Bert"/>
    <property name="securementPasswordType" value="PasswordText"/>
    <property name="securementUsernameTokenElements" value="Nonce Created"/>
</bean>
----
====

==== Certificate Authentication

As certificate authentication is akin to digital signatures, WSS4J handles it as part of the signature validation and securement.
Specifically, the `securementSignatureKeyIdentifier` property must be set to `DirectReference` in order to instruct WSS4J to generate a `BinarySecurityToken` element containing the X509 certificate and to include it in the outgoing message.
The certificate's name and password are passed through the `securementUsername` and `securementPassword` properties, respectively, as the following example shows:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="securementActions" value="Signature"/>
    <property name="securementSignatureKeyIdentifier" value="DirectReference"/>
    <property name="securementUsername" value="mycert"/>
    <property name="securementPassword" value="certpass"/>
    <property name="securementSignatureCrypto">
      <bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
        <property name="keyStorePassword" value="123456"/>
        <property name="keyStoreLocation" value="classpath:/keystore.jks"/>
      </bean>
    </property>
</bean>
----
====

For the certificate validation, regular signature validation applies:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="validationActions" value="Signature"/>
    <property name="validationSignatureCrypto">
      <bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
        <property name="keyStorePassword" value="123456"/>
        <property name="keyStoreLocation" value="classpath:/keystore.jks"/>
      </bean>
    </property>
</bean>
----
====

At the end of the validation, the interceptor automatically verifies the validity of the certificate by delegating to the default WSS4J implementation.
If needed, you can change this behavior by redefining the `verifyCertificateTrust` method.

For more detail, see to <<security-wss4j-digital-signatures>>.

=== Security Timestamps

This section describes the various timestamp options available in the `Wss4jSecurityInterceptor`.

==== Validating Timestamps

To validate timestamps, add `Timestamp` to the `validationActions` property.
You can override timestamp semantics specified by the initiator of the SOAP message by setting `timestampStrict` to `true` and specifying a server-side time-to-live in seconds (default: 300) by setting the `timeToLive` property.
The interceptor always rejects already expired timestamps, whatever the value of `timeToLive` is.

In the following example, the interceptor limits the timestamp validity window to 10 seconds, rejecting any valid timestamp token outside that window:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="validationActions" value="Timestamp"/>
    <property name="timestampStrict" value="true"/>
    <property name="timeToLive" value="10"/>
</bean>

----
====

==== Adding Timestamps

Adding `Timestamp` to the `securementActions` property generates a timestamp header in outgoing messages.
The `timestampPrecisionInMilliseconds` property specifies whether the precision of the generated timestamp is in milliseconds.
The default value is `true`.
The following listing adds a timestamp:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="securementActions" value="Timestamp"/>
    <property name="timestampPrecisionInMilliseconds" value="true"/>
</bean>
----
====

[[security-wss4j-digital-signatures]]
=== Digital Signatures

This section describes the various signature options available in the `Wss4jSecurityInterceptor`.

==== Verifying Signatures

To instruct the `Wss4jSecurityInterceptor`, `validationActions` must contain the `Signature` action.
Additionally, the `validationSignatureCrypto` property must point to the keystore containing the public certificates of the initiator:

====
[source,xml]
----
<bean id="wsSecurityInterceptor" class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="validationActions" value="Signature"/>
    <property name="validationSignatureCrypto">
        <bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
            <property name="keyStorePassword" value="123456"/>
            <property name="keyStoreLocation" value="classpath:/keystore.jks"/>
        </bean>
    </property>
</bean>
----
====

==== Signing Messages

Signing outgoing messages is enabled by adding the `Signature` action to the `securementActions`.
The alias and the password of the private key to use are specified by the `securementUsername` and `securementPassword` properties, respectively. `securementSignatureCrypto` must point to the keystore that contains the private key:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="securementActions" value="Signature"/>
    <property name="securementUsername" value="mykey"/>
    <property name="securementPassword" value="123456"/>
    <property name="securementSignatureCrypto">
        <bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
            <property name="keyStorePassword" value="123456"/>
            <property name="keyStoreLocation" value="classpath:/keystore.jks"/>
        </bean>
    </property>
</bean>
----
====

Furthermore, you can define the signature algorithm by setting the `securementSignatureAlgorithm` property.

You can customize the key identifier type to use by setting the `securementSignatureKeyIdentifier` property.
Only `IssuerSerial` and `DirectReference` are valid for the signature.

The `securementSignatureParts` property controls which part of the message is signed.
The value of this property is a list of semicolon-separated element names that identify the elements to sign.
The general form of a signature part is `{}{namespace}Element`.
Note that the first empty brackets are used for encryption parts only.
The default behavior is to sign the SOAP body.

The following example shows how to sign the `echoResponse` element in the Spring-WS echo sample:

====
[source,xml]
----
<property name="securementSignatureParts"
    value="{}{http://www.springframework.org/spring-ws/samples/echo}echoResponse"/>
----
====

To specify an element without a namespace, use the string, `Null` (case sensitive), as the namespace name.

If no other element in the request has a local name of `Body`, the SOAP namespace identifier can be empty (`{}`).

==== Signature Confirmation

Signature confirmation is enabled by setting `enableSignatureConfirmation` to `true`.
Note that the signature confirmation action spans over the request and the response.
This implies that `secureResponse` and `validateRequest` must be set to `true` (which is the default value) even if there are no corresponding security actions.
The following example sets the `enableSignatureConfirmation` property to `true`:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
    <property name="validationActions" value="Signature"/>
    <property name="enableSignatureConfirmation" value="true"/>
    <property name="validationSignatureCrypto">
        <bean class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
            <property name="keyStorePassword" value="123456"/>
            <property name="keyStoreLocation" value="file:/keystore.jks"/>
        </bean>
    </property>
</bean>
----
====

=== Decryption and Encryption

This section describes the various decryption and encryption options available in the `Wss4jSecurityInterceptor`.

==== Decryption

Decryption of incoming SOAP messages requires that the `Encrypt` action be added to the `validationActions` property.
The rest of the configuration depends on the key information that appears in the message.
(This is because WSS4J needs only a Crypto for encrypted keys, whereas embedded key name validation is delegated to a callback handler).

To decrypt messages with an embedded encrypted symmetric key (the `xenc:EncryptedKey` element), `validationDecryptionCrypto` needs to point to a keystore that contains the decryption private key.
Additionally, `validationCallbackHandler` has to be injected with a {spring-ws-api}/soap/security/wss4j2/callback/KeyStoreCallbackHandler.html[`KeyStoreCallbackHandler`] that specifies the key's password:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
    <property name="validationActions" value="Encrypt"/>
    <property name="validationDecryptionCrypto">
        <bean class="org.springframework.ws.soap.security.wss4j2.support.CryptoFactoryBean">
            <property name="keyStorePassword" value="123456"/>
            <property name="keyStoreLocation" value="classpath:/keystore.jks"/>
        </bean>
    </property>
    <property name="validationCallbackHandler">
        <bean class="org.springframework.ws.soap.security.wss4j2.callback.KeyStoreCallbackHandler">
            <property name="privateKeyPassword" value="mykeypass"/>
        </bean>
    </property>
</bean>
----
====

To support decryption of messages with an embedded key name ( `ds:KeyName` element), you can configure a `KeyStoreCallbackHandler` that points to the keystore with the symmetric secret key.
The `symmetricKeyPassword` property indicates the key's password, the key name being the one specified by `ds:KeyName` element:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
    <property name="validationActions" value="Encrypt"/>
    <property name="validationCallbackHandler">
        <bean class="org.springframework.ws.soap.security.wss4j2.callback.KeyStoreCallbackHandler">
            <property name="keyStore">
                <bean class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
                    <property name="location" value="classpath:keystore.jks"/>
                    <property name="type" value="JCEKS"/>
                    <property name="password" value="123456"/>
                </bean>
            </property>
            <property name="symmetricKeyPassword" value="mykeypass"/>
        </bean>
    </property>
</bean>
----
====

==== Encryption

Adding `Encrypt` to the `securementActions` enables encryption of outgoing messages.
You can set the certificate's alias to use for the encryption by setting the `securementEncryptionUser` property.
The keystore where the certificate resides is accessed through the `securementEncryptionCrypto` property.
As encryption relies on public certificates, no password needs to be passed.
The following example uses the `securementEncryptionCrypto` property:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
    <property name="securementActions" value="Encrypt"/>
    <property name="securementEncryptionUser" value="mycert"/>
    <property name="securementEncryptionCrypto">
        <bean class="org.springframework.ws.soap.security.wss4j2.support.CryptoFactoryBean">
            <property name="keyStorePassword" value="123456"/>
            <property name="keyStoreLocation" value="file:/keystore.jks"/>
        </bean>
    </property>
</bean>
----
====

You can customize encryption in several ways: The key identifier type to use is defined by the `securementEncryptionKeyIdentifier` property.
Possible values are `IssuerSerial`,`X509KeyIdentifier`, `DirectReference`,`Thumbprint`, `SKIKeyIdentifier`, and `EmbeddedKeyName`.

If you choose the `EmbeddedKeyName` type, you need to specify the secret key to use for the encryption.
The alias of the key is set in the `securementEncryptionUser` property, as for the other key identifier types.
However, WSS4J requires a callback handler to fetch the secret key.
Thus, you must provide `securementCallbackHandler` with a `KeyStoreCallbackHandler` that points to the appropriate keystore.
By default, the `ds:KeyName` element in the resulting WS-Security header takes the value of the `securementEncryptionUser` property.
To indicate a different name, you can set the `securementEncryptionEmbeddedKeyName` with the desired value.
In the next example, the outgoing message is encrypted with a key aliased `secretKey`, whereas `myKey` appears in `ds:KeyName` element:

====
[source,xml]
----
<bean class="org.springframework.ws.soap.security.wss4j2.Wss4jSecurityInterceptor">
    <property name="securementActions" value="Encrypt"/>
    <property name="securementEncryptionKeyIdentifier" value="EmbeddedKeyName"/>
    <property name="securementEncryptionUser" value="secretKey"/>
    <property name="securementEncryptionEmbeddedKeyName" value="myKey"/>
    <property name="securementCallbackHandler">
        <bean class="org.springframework.ws.soap.security.wss4j2.callback.KeyStoreCallbackHandler">
            <property name="symmetricKeyPassword" value="keypass"/>
            <property name="keyStore">
                <bean class="org.springframework.ws.soap.security.support.KeyStoreFactoryBean">
                    <property name="location" value="file:/keystore.jks"/>
                    <property name="type" value="jceks"/>
                    <property name="password" value="123456"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>
----
====

The `securementEncryptionKeyTransportAlgorithm` property defines which algorithm to use to encrypt the generated symmetric key.
Supported values are `http://www.w3.org/2001/04/xmlenc#rsa-1_5`, which is the default, and `http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p`.

You can set the symmetric encryption algorithm to use by setting the `securementEncryptionSymAlgorithm` property.
Supported values are `http://www.w3.org/2001/04/xmlenc#aes128-cbc` (default), `http://www.w3.org/2001/04/xmlenc#tripledes-cbc`, `http://www.w3.org/2001/04/xmlenc#aes256-cbc`, and `http://www.w3.org/2001/04/xmlenc#aes192-cbc`.

Finally, the `securementEncryptionParts` property defines which parts of the message are encrypted.
The value of this property is a list of semicolon-separated element names that identify the elements to encrypt.
An encryption mode specifier and a namespace identification, each inside a pair of curly brackets, may precede each element name.
The encryption mode specifier is either `{Content}` or `{Element}` See the W3C XML Encryption specification about the differences between Element and Content encryption.
The following example identifies the `echoResponse` from the echo sample:

====
[source,xml]
----
<property name="securementEncryptionParts"
    value="{Content}{http://www.springframework.org/spring-ws/samples/echo}echoResponse"/>
----
====

Be aware that the element name, the namespace identifier, and the encryption modifier are case-sensitive.
You can omit the encryption modifier and the namespace identifier.
If you do, the encryption mode defaults to `Content`, and the namespace is set to the SOAP namespace.

To specify an element without a namespace, use the value, `Null` (case sensitive), as the namespace name.
If no list is specified, the handler encrypts the SOAP Body in `Content` mode by default.

=== Security Exception Handling

The exception handling of the `Wss4jSecurityInterceptor` is identical to that of the `XwsSecurityInterceptor`.
See <<security-xws-exception-handling>> for more information.
