The standard WS-SecurityPolicy policies are designed to specify security requirements in some detail: for example, security protocols, security algorithms, token types, authentication requirements, and so on, are all described. But the standard policy assertions do not provide any mechanism for specifying associated security data, such as keys and credentials. WS-SecurityPolicy expects that the requisite security data is provided through a proprietary mechanism. In Fuse Services Framework, the associated security data is provided through Spring XML configuration.
You can specify an application's encryption keys and signing keys by setting properties on a client's request context or on an endpoint context (see Add encryption and signing properties to Spring configuration). The properties you can set are shown in Table 6.1.
Table 6.1. Encryption and Signing Properties
Property | Description |
---|---|
ws-security.signature.properties | The WSS4J properties file/object that contains the WSS4J properties for
configuring the signature keystore (which is also used for decrypting) and
Crypto objects. |
ws-security.signature.username | (Optional) The username or alias of the key in the signature keystore to use. If not specified, the alias set in the properties file is used. If that is also not set, and the keystore only contains a single key, that key will be used. |
ws-security.encryption.properties | The WSS4J properties file/object that contains the WSS4J properties for
configuring the encryption keystore (which is also used for validating signatures)
and Crypto objects. |
ws-security.encryption.username | (Optional) The username or alias of the key in the encryption keystore to use. If not specified, the alias set in the properties file is used. If that is also not set, and the keystore only contains a single key, that key will be used. |
![]() | Tip |
---|---|
The names of the preceding properties are not so well chosen, because they do not
accurately reflect what they are used for. The key specified by
|
Before you can use any WS-Policy policies in a Fuse Services Framework application, you must add
the policies feature to the default CXF bus. Add the p:policies
element to
the CXF bus, as shown in the following Spring configuration fragment:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:p="http://cxf.apache.org/policy" ... >
<cxf:bus>
<cxf:features>
<p:policies/>
<cxf:logging/>
</cxf:features>
</cxf:bus>
...
</beans>
The following example shows how to add signature and encryption properties to proxies
of the specified service type (where the service name is specified by the
name
attribute of the jaxws:client
element). The properties
are stored in WSS4J property files, where alice.properties
contains the
properties for the signature key and bob.properties
contains the properties
for the encryption key.
<beans ... > <jaxws:client name="{http://InteropBaseAddress/interop}MutualCertificate10SignEncrypt_IPingService" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.signature.properties" value="etc/alice.properties"/> <entry key="ws-security.encryption.properties" value="etc/bob.properties"/> </jaxws:properties> </jaxws:client> ... </beans>
In fact, although it is not obvious from the property names, each of these keys is used for two distinct purposes on the client side:
alice.properties
(that is, the key specified byws-security.signature.properties
) is used on the client side as follows:For signing outgoing messages.
For decrypting incoming messages.
bob.properties
(that is, the key specified byws-security.encryption.properties
) is used on the client side as follows:For encrypting outgoing messages.
For verifying signatures on incoming messages.
If you find this confusing, see Basic Signing and Encryption Scenario for a more detailed explanation.
The following example shows how to add signature and encryption properties to a JAX-WS
endpoint. The properties file, bob.properties
, contains the properties for
the signature key and the properties file, alice.properties
, contains the
properties for the encryption key (this is the inverse of the client
configuration).
<beans ... > <jaxws:endpoint name="{http://InteropBaseAddress/interop}MutualCertificate10SignEncrypt_IPingService" id="MutualCertificate10SignEncrypt" address="http://localhost:9002/MutualCertificate10SignEncrypt" serviceName="interop:PingService10" endpointName="interop:MutualCertificate10SignEncrypt_IPingService" implementor="interop.server.MutualCertificate10SignEncrypt"> <jaxws:properties> <entry key="ws-security.signature.properties" value="etc/bob.properties"/> <entry key="ws-security.encryption.properties" value="etc/alice.properties"/> </jaxws:properties> </jaxws:endpoint> ... </beans>
Each of these keys is used for two distinct purposes on the server side:
bob.properties
(that is, the key specified byws-security.signature.properties
) is used on the server side as follows:For signing outgoing messages.
For decrypting incoming messages.
alice.properties
(that is, the key specified byws-security.encryption.properties
) is used on the server side as follows:For encrypting outgoing messages.
For verifying signatures on incoming messages.
Fuse Services Framework uses WSS4J property files to load the public keys and the private keys needed for encryption and signing. Table 6.2 describes the properties that you can set in these files.
Table 6.2. WSS4J Keystore Properties
Property | Description |
---|---|
|
Specifies an implementation of the The rest of the properties in this table are specific to the
Merlin implementation of the |
|
(Optional) The name of the JSSE keystore provider to
use. The default keystore provider is Bouncy
Castle. You can switch provider to Sun's JSSE keystore provider by
setting this property to |
| The Bouncy Castle keystore provider supports the following types of keystore:
JKS and PKCS12 . In addition, Bouncy Castle supports
the following proprietary keystore types: BKS and UBER. |
| Specifies the location of the keystore file to load, where the location is specified relative to the Classpath. |
| (Optional) If the keystore type is JKS
(Java keystore), you can select a specific key from the keystore by specifying its
alias. If the keystore contains only one key, there is no need to specify an
alias. |
| The password specified by this property is used for two purposes: to unlock the keystore (keystore password) and to decrypt a private key that is stored in the keystore (private key password). Hence, the keystore password must be same as the private key password. |
For example, the etc/alice.properties
file contains property settings to
load the PKCS#12 file, certs/alice.pfx
, as follows:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=PKCS12 org.apache.ws.security.crypto.merlin.keystore.password=password org.apache.ws.security.crypto.merlin.keystore.file=certs/alice.pfx
The etc/bob.properties
file contains property settings to load the
PKCS#12 file, certs/bob.pfx
, as follows:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.password=password # for some reason, bouncycastle has issues with bob.pfx org.apache.ws.security.crypto.merlin.keystore.provider=SunJSSE org.apache.ws.security.crypto.merlin.keystore.type=PKCS12 org.apache.ws.security.crypto.merlin.keystore.file=certs/bob.pfx
An alternative approach to loading encryption keys and signing keys is to use the
properties shown in Table 6.3 to
specify Crypto
objects that load the relevant keys. This requires you to
provide your own implementation of the WSS4J Crypto
interface,
org.apache.ws.security.components.crypto.Crypto
.
Table 6.3. Properties for Specifying Crypto Objects
Property | Description |
---|---|
ws-security.signature.crypto | Specifies an instance of a Crypto object that is responsible for
loading the keys for signing and decrypting messages. |
ws-security.encryption.crypto | Specifies an instance of a Crypto object that is responsible for
loading the keys for encrypting messages and verifying signatures. |
Example 6.7 shows the definition of the
Crypto
interface that you can implement, if you want to provide encryption
keys and signing keys by programming. For more information, see the WSS4J home page.
Example 6.7. WSS4J Crypto Interface
// Java package org.apache.ws.security.components.crypto; import org.apache.ws.security.WSSecurityException; import java.io.InputStream; import java.math.BigInteger; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; public interface Crypto { X509Certificate loadCertificate(InputStream in) throws WSSecurityException; X509Certificate[] getX509Certificates(byte[] data, boolean reverse) throws WSSecurityException; byte[] getCertificateData(boolean reverse, X509Certificate[] certs) throws WSSecurityException; public PrivateKey getPrivateKey(String alias, String password) throws Exception; public X509Certificate[] getCertificates(String alias) throws WSSecurityException; public String getAliasForX509Cert(Certificate cert) throws WSSecurityException; public String getAliasForX509Cert(String issuer) throws WSSecurityException; public String getAliasForX509Cert(String issuer, BigInteger serialNumber) throws WSSecurityException; public String getAliasForX509Cert(byte[] skiBytes) throws WSSecurityException; public String getDefaultX509Alias(); public byte[] getSKIBytesFromCert(X509Certificate cert) throws WSSecurityException; public String getAliasForX509CertThumb(byte[] thumb) throws WSSecurityException; public KeyStore getKeyStore(); public CertificateFactory getCertificateFactory() throws WSSecurityException; public boolean validateCertPath(X509Certificate[] certs) throws WSSecurityException; public String[] getAliasesForDN(String subjectDN) throws WSSecurityException; }