Apache WSS4J™ User Guide

What is Apache WSS4J™?

In this section we describe what Apache WSS4J is and what functionality it supports. For more information about how to use WSS4J, see the Using Apache WSS4J page.

The technical answer

The technical answer is that Apache WSS4J provides a Java implementation of the primary security standards for Web Services, namely the OASIS Web Services Security (WS-Security) specifications from the OASIS Web Services Security TC. WSS4J provides an implementation of the following WS-Security standards:

The less technical answer

Apache WSS4J is designed to be used with a Web Services stack such as Apache CXF or Apache Axis to secure SOAP messages. It offers the following high level functionality:

  • Message Confidentiality

  • Message Integrity

  • Message Authentication

  • Message Authorization

WSS4J uses the functionality of Apache Santuario to encrypt SOAP Messages. Typically, the SOAP Body as well as a UsernameToken in the security header are encrypted. WSS4J supports both Symmetric and Asymmetric encryption. Typically, a Symmetric Key is generated and used to encrypt the SOAP Body/UsernameToken, and then the Symmetric Key is in turn encrypted by the public key of the recipient and included in the security header of the request.

WSS4J also provides the ability to ensure message integrity by applying XML Signature to a SOAP request. Typically, the SOAP Body, Timestamp, WS-Addressing headers, as well as any other token in the security header are signed. Both Symmetric and Asymmetric Signature are supported. WSS4J supports using a secret key associated with a token, such as a Kerberos Token or a key derived from a UsernameToken, to sign (as well as to encrypt) a request.

As well as providing message confidentiality and integrity, WSS4J allows for client authentication in a number of different ways. The most common way is to include a username and password in a UsernameToken included in the security header. The message recipient can plug in a WSS4J Validator to validate the received credentials. Authentication is also supported via Kerberos Tokens, SAML Assertions (when used with "HolderOfKey"), and Asymmetric Signature.

Finally, WSS4J supports message authorization using an RBAC approach. This can be supported via the use-case of UsernameTokens validated using the JAAS Validator that ships with WSS4J. This stores the JAAS Subject in the WSS4J results list, and can be used by the web services stack to populate a security context. Similarly, authorization can be supported using Claims extracted from a SAML (Attribute) Assertion.

Using Apache WSS4J™

This page describes how to use Apache WSS4J. For information about how to configure WSS4J, see the configuration page. WSS4J can essentially be used in three different ways. For information about using WSS4J with a SOAP stack, see the sections on Apache CXF and Apache Rampart/Axis.

  • Action based approach: WSS4J offers an "Action" based approach to applying WS-Security to a SOAP request or response, in conjunction with a SOAP stack.

  • WS-SecurityPolicy based approach: WSS4J can be configured for a SOAP request/response via WS-SecurityPolicy, in conjunction with a SOAP Stack. This is the recommended approach.

  • Standalone approach: WSS4J offers a low-level (DOM) API to construct/sign/encrypt/etc. tokens directly.

Action based approach

The WSHandler class in WSS4J is designed to configure WSS4J to secure an outbound SOAP request, by parsing configuration that is supplied to it via a subclass. Typically a web services stack that uses WSS4J for WS-Security will subclass WSHandler. An example of a subclass is the WSS4JOutInterceptor in Apache CXF. The configuration tags are defined in the ConfigurationConstants class (WSHandlerConstants in WSS4J 1.6.x). For a more detailed explanation of the configuration tags, please refer to the configuration page. The next few paragraphs will describe the most fundamental configuration tags that are used in most cases.

Common configuration tags

The "Action" based approach to using Apache WSS4J involves explicitly telling WSS4J what WS-Security functionality to perform on a request, by configuring the stack specific WSHandler implementation with the required properties. On the receiving side, the "actions" that are configured are matched against what was processed in the security header, and an error is thrown if they do not match (in some order). Typical actions include "UsernameToken, "Signature", "Encrypt", "Timestamp, "SAMLTokenSigned", etc.

After specifying the action to perform on a request, the next task is typically to specify the "user". The "user" can be either the username to insert into a UsernameToken, or the keystore alias to use for either signature or encryption. If you are configuring more than one of these actions, the "signatureUser" and "encryptionUser" configuration tags override the more general "user" tag. The next task is often to specify a CallbackHandler implementation to use to retrieve passwords. On the sending side, this is used to retrieve a password to insert into a UsernameToken and to decrypt a private key from a keystore for Signature. On the receiving side, it is used to retrieve a password to validate a received UsernameToken, and to decrypt a private key from a keystore to use for decryption.

The next task is to specify a Crypto implementation if you are using Signature or Encryption. See the configuration page for more information on the Crypto interface. Typically, it is configured in a Crypto properties file, which specifies the Crypto implementation to use, as well as the keystore location, default alias/password, etc. For signature, the path of this properties file can be referred to by the tag "signaturePropFile" and "encryptionPropFile" for outbound request, and "signatureVerificationPropFile" and "decryptionPropFile" for inbound requests". How signing keys/certificates are referenced from a Signature can be controlled via the "signatureKeyIdentifier" configuration tag. This defaults to "IssuerSerial", but could be "DirectReference", "Thumbprint", etc. The "encryptionKeyIdentifier" tag performs the same function for encryption.

Finally, the Elements to sign or encrypt can be specified by the "signatureParts" and "encryptionParts" configuration tags. Both default to the SOAP Body. The value of signatureParts/encryptionParts is a list of semi-colon separated values that identify the elements to sign/encrypt. The value is of the format of an encryption mode specifier, and a namespace URI, each inside a pair of curly brackets, and then the local name of the Element. For example, "{Content}{http://example.org/paymentv2}CreditCard;". The encryption modifier can be either "Content" or "Element" and only applies to encryption.

Here are some sample configuration values for various actions, as taken from some CXF system tests. The constructor of the WSS4JOutInterceptor/WSS4JInIntereptor interceptors in CXF takes a map of String/Object pairs which correspond to the key/value pairs given in the tables below. See the CXF configuration file for more information.

Sample Outbound UsernameToken configuration

Sample Outbound Signature/Timestamp configuration

  • Key - Value

  • action - Signature Timestamp

  • signatureUser - alice

  • passwordCallbackClass - org.apache.cxf.systest.ws.common.KeystorePasswordCallback

  • signaturePropFile - alice.properties

  • signatureKeyIdentifier - DirectReference

  • signatureParts - {}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{}{http://schemas.xmlsoap.org/soap/envelope/}Body;

WS-SecurityPolicy based approach

The recommended way of applying WS-Security to your web services is to use WS-SecurityPolicy. The WS-SecurityPolicy specification defines a set of WS-Policy expressions that can be used to define the security requirements of a web service. Typically one or more policies are attached to the WSDL of a service, which conveys the security requirements of the service to the client. A WS-SecurityPolicy aware stack such as Apache CXF or Apache Axis/Rampart can parse the policies and configure WSS4J appropriately. This greatly simplifies things for the user, who then only has to supply some basic information about which users, CallbackHandlers, Crypto property files, etc. to use.

For more information on using WS-SecurityPolicy with WSS4J, please see CXF’s WS-SecurityPolicy page, or go to the SOAP stack sections below: CXF WS-SecurityPolicy configuration

Standalone approach

Apache WSS4J provides a set of APIs to implement WS-Security functionality on a SOAP message. It is possible to use these APIs directly in a standalone manner, although it is far more common to use either the "Action" or WS-SecurityPolicy based approaches. This functionality is only available for the DOM code. The best way of finding out how to do this is to take a look at the test sources. For example:

SOAP Stacks

Apache CXF

Apache CXF is an open-source web services stack. CXF uses WSS4J to perform the core WS-Security functionality, and provides extended security functionality based around the WS-SecurityPolicy, WS-SecureConversation and WS-Trust specifications. More information:

Apache Rampart/Axis

Apache Rampart is the security module for the Axis2 web services stack. Rampart uses WSS4J to perform the core WS-Security functionality, and provides extended security functionality based around the WS-SecurityPolicy, WS-SecureConversation and WS-Trust specifications. Note that support for Apache Axis1 via the WSS4J 1.5.x series of releases is no longer supported. More information:

Apache WSS4J Migration Guides

Information about migrating to various new versions of WSS4J is provided in this section.

Apache WSS4J 2.2.0 Migration Guide

This section is a migration guide for helping Apache WSS4J 2.1.x users to migrate to the 2.2.x releases.

JDK8 minimum requirement

WSS4J 2.1.x required JDK7 as a minimum requirement. WSS4J 2.2.x requires at least JDK8.

Base64 changes

In WSS4J 2.1.x, the Base64 implementation that ships with the JDK (java.util.Base64) is used, instead of the Base64 implementation that ships with Apache Santuario. It is unlikely, but this may have an impact on users who are parsing messages with Base64 implementations that depend on specific CR or LF characters, as the Santuario and Java Base64 implementations differ slightly. Both the Apache Santuario and Java Base64 implementations can correctly decode the messages created with Apache WSS4J 2.2.x.

Kerberos changes

There are some changes with regards to Kerberos in WSS4J 2.1.x. The KerberosClientAction and KerberosServiceAction classes are removed. Instead use KerberosClientExceptionAction and KerberosServiceExceptionAction in the same package. The KerberosTokenDecoderImpl is removed as we can now get access to the secret key via the JDK APIs. As a consequence, the ws-security-common module no longer has a dependency on Apache Directory.

Apache WSS4J 2.1.0 Migration Guide

This section is a migration guide for helping Apache WSS4J 2.0.x users to migrate to the 2.1.x releases.

JDK7 minimum requirement

WSS4J 2.0.x required JDK6 as a minimum requirement. WSS4J 2.1.x requires at least JDK7. The Xerces and xml-api dependencies have been removed from the DOM code, as they are no longer required due to the JDK7 minimum requirement.

OpenSAML 3.x migration

A key dependency change in WSS4J 2.1.0 is the upgrade from OpenSAML 2.x to 3.x (currently 3.1.0). OpenSAML 3.x contains a large number of package changes. Therefore if you have any OpenSAML dependencies in a CallbackHandler used to create SAML Assertions in WSS4J, code changes will be required.

The most common OpenSAML dependency is to include a "SAMLVersion" to tell the SAMLCallback whether to create a SAML 2.0 or 1.1 Assertion. WSS4J 2.1 provides an alternative way of specifying the SAML Version, via a Version bean. See here for an example.

Custom processor changes

If you have a custom Processor instance to process a token in the security header in some custom way, you must add the WSSecurityEngineResult that is generated by the processing, to the WSDocInfo Object via the "addResult" method. Otherwise, it will not be available when security results are retrieved and processed.

Apache WSS4J 2.0.0 Migration Guide

This section is a migration guide for helping Apache WSS4J 1.6.x users to migrate to the 2.0.x releases. Also see the new features page for more information about the new functionality available in WSS4J 2.0.x.

Migrating to using the streaming (StAX) code

WSS4J 2.0.0 introduces a streaming (StAX-based) WS-Security implementation to complement the existing DOM-based implementation. The DOM-based implementation is quite performant and flexible, but having to read the entire request into memory carries performance penalties. The StAX-based code offers largely the same functionality as that available as part of the DOM code, and is configured in mostly the same way (via configuration tags that are shared between both stacks).

As of the time of writing, Apache CXF is the only web services stack to integrate the new WS-Security streaming functionality. To switch to use the streaming code for the manual "Action" based approach, simply change the outbound and inbound interceptors as follows:

  • "org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" to "org.apache.cxf.ws.security.wss4j.WSS4JStaxOutInterceptor".

  • "org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" to "org.apache.cxf.ws.security.wss4j.WSS4JStaxInInterceptor".

For the WS-SecurityPolicy based approach of configuring WS-Security, simply set the JAX-WS property SecurityConstants.ENABLE_STREAMING_SECURITY ("ws-security.enable.streaming") to "true".

For more information on the streaming functionality available in WSS4J 2.0.0, please see the streaming documentation page.

Crypto/CallbackHandler changes

Typically, a user configures Signature and Encryption keys via a Crypto properties file. In WSS4J 1.6.x, the property names all start with "org.apache.ws.security.crypto.*". In WSS4J 2.0.0, the new prefix is "org.apache.wss4j.crypto.\*". However, WSS4J 2.0.0 will accept the older prefix value. No other changes are necessary for migrating Crypto properties.

In WSS4J 1.6.x, it was only possible to specify a Crypto implementation for both Signature Creation + Verification. In WSS4J 2.0.0, there is now a separate Signature Verification Crypto instance, that can be configured via the following configuration tags:

  • signatureVerificationPropFile - The path of the crypto property file to use for Signature verification.

  • signatureVerificationPropRefId - The key that holds a reference to the object holding complete information about the signature verification Crypto implementation.

In WSS4J, you need to define a CallbackHandler to supply a password to a WSPasswordCallback Object when dealing with UsernameTokens, or to unlock private keys for Signature creation, etc. In WSS4J 2.0.0, the functionality is exactly the same, except that the package of the WSPasswordCallback Object has changed from "org.apache.ws.security" to "org.apache.wss4j.common.ext". Any CallbackHandler implementation will need to be updated to use the new package.

SAML Assertion changes

A CallbackHandler implementation is required to create a SAML Assertion, by populating various beans. Similar to the WSPasswordCallback package change, there are also some package changes for SAML. The base package for the SAMLCallback class, and of the various "bean" classes, has changed from "org.apache.ws.security.saml.ext" to "org.apache.wss4j.common.saml".

Apache WSS4J 1.6.x uses the SAMLIssuer interface to configure the creation and signing of a SAML Assertion. In Apache WSS4J 2.0.0, the SAMLIssuer functionality has been moved to the SAMLCallback, so that the CallbackHandler used to create a SAML Assertion is responsible for all of the signing configuration as well. Therefore, the properties file that is used in WSS4J 1.6.x to sign a SAML Assertion is no longer used in WSS4J 2.0.0, and the "samlPropFile" and "samlPropRefId" configuration tags have been removed.

The SAMLCallback Object contains the additional properties in WSS4J 2.0.0 that can be set to sign the Assertion:

  • boolean signAssertion - Whether to sign the assertion or not (default "false").

  • String issuerKeyName - The keystore alias for signature

  • String issuerKeyPassword - The keystore password for the alias

  • Crypto issuerCrypto - The Crypto instance used for signature

  • boolean sendKeyValue - Whether to send the keyvalue or the X509Certificate (default "false").

  • String canonicalizationAlgorithm - The C14n algorithm to use for signature.

  • String signatureAlgorithm - The Signature algorithm.

Configuration tag changes

In WSS4J 1.6.x, configuration tags were configured in the WSHandlerConstants class. In WSS4J 2.0.0, both the DOM and StAX-based code largely share the same configuration options, and so the configuration tags are defined in ConfigurationConstants. Note that the WSS4J 1.6.x configuration class (WSHandlerConstants) extends this class in WSS4J 2.0.0, so there is no need to change any configuration code when upgrading.

The configuration tags that have been removed and added are detailed below. The non-standard key derivation and UsernameToken Signature functionality that was optional in WSS4J 1.6.x has been removed. Some new actions are added for the streaming code, as well as some options surrounding caching. An important migration point is that there is now a separate configuration tag used for verifying signatures. In WSS4J 1.6.x, there was only one tag used for both signature creation and verification.

Removed Configuration tags in WSS4J 2.0.0

This section details the Configuration tags that are no longer present in WSS4J 2.0.0.

  • SIGN_WITH_UT_KEY (UsernameTokenSignature) - Perform a .NET specific signature using a Username Token action. Removed as it was not standard compliant.

  • PASSWORD_TYPE_STRICT (passwordTypeStrict) - Whether to enable strict Username Token password type handling. In WSS4J 2.0.0 this functionality can be enabled by just setting the required PASSWORD_TYPE.

  • USE_DERIVED_KEY (useDerivedKey) - Whether to use the standard UsernameToken Key Derivation algorithm. Removed as only the standard algorithm is used in WSS4J 2.0.0.

  • ENC_KEY_NAME (embeddedKeyName) - The text of the key name to be sent in the KeyInfo for encryption. Embedded KeyNames are not supported in WSS4J 2.0.0.

  • ADD_UT_ELEMENTS (addUTElements) - Additional elements to add to a Username Token, i.e. "nonce" and "created". See the ADD_USERNAMETOKEN_NONCE and ADD_USERNAMETOKEN_CREATED properties below.

  • WSE_SECRET_KEY_LENGTH (wseSecretKeyLength) - The length of the secret (derived) key to use for the WSE UT_SIGN functionality. Removed as it is not standard compliant.

  • ENC_CALLBACK_CLASS (embeddedKeyCallbackClass) - The CallbackHandler implementation class used to get the key associated with a key name. KeyName is not supported in WSS4J 2.0.0.

  • ENC_CALLBACK_REF (embeddedKeyCallbackRef) -The CallbackHandler implementation object used to get the key associated with a key name. KeyName is not supported in WSS4J 2.0.0.

New Configuration tags in WSS4J 2.0.0

This section details the new Configuration tags in WSS4J 2.0.0.

  • USERNAME_TOKEN_SIGNATURE (UsernameTokenSignature) - Perform a UsernameTokenSignature action.

  • SIGNATURE_DERIVED (SignatureDerived) - Perform a Signature action with derived keys.

  • ENCRYPT_DERIVED (EncryptDerived) - Perform a Encryption action with derived keys.

  • SIGNATURE_WITH_KERBEROS_TOKEN (SignatureWithKerberosToken) - Perform a Signature action with a kerberos token. Only for StAX code.

  • ENCRYPT_WITH_KERBEROS_TOKEN (EncryptWithKerberosToken) - Perform a Encryption action with a kerberos token. Only for StAX code.

  • KERBEROS_TOKEN (KerberosToken) - Add a kerberos token.

  • CUSTOM_TOKEN (CustomToken) - Add a "Custom" token from a CallbackHandler

  • SIG_VER_PROP_FILE (signatureVerificationPropFile) - The path of the crypto property file to use for Signature verification.

  • SIG_VER_PROP_REF_ID (signatureVerificationPropRefId) - The String ID that is used to store a reference to the Crypto object or the Crypto Properties object for Signature verification.

  • ALLOW_RSA15_KEY_TRANSPORT_ALGORITHM (allowRSA15KeyTransportAlgorithm) - Whether to allow the RSA v1.5 Key Transport Algorithm or not. Default is "false".

  • ADD_INCLUSIVE_PREFIXES (addInclusivePrefixes) - Whether to add an InclusiveNamespaces PrefixList as a CanonicalizationMethod child when generating Signatures using WSConstants.C14N_EXCL_OMIT_COMMENTS. Default is "true".

  • ADD_USERNAMETOKEN_NONCE (addUsernameTokenNonce) - Whether to add a Nonce Element to a UsernameToken (for plaintext). Default is "false"

  • ADD_USERNAMETOKEN_CREATED (addUsernameTokenCreated) - Whether to add a Created Element to a UsernameToken (for plaintext). Default is "false"

  • ALLOW_USERNAMETOKEN_NOPASSWORD (allowUsernameTokenNoPassword) - Whether a UsernameToken with no password element is allowed. Default is "false".

  • VALIDATE_SAML_SUBJECT_CONFIRMATION (validateSamlSubjectConfirmation) - Whether to validate the SubjectConfirmation requirements of a received SAML Token (sender-vouches or holder-of-key). Default is "true".

  • INCLUDE_SIGNATURE_TOKEN (includeSignatureToken) - Whether to include the Signature Token in the security header as well or not (for IssuerSerial + Thumbprint cases). Default is "false"

  • INCLUDE_ENCRYPTION_TOKEN (includeEncryptionToken) - Whether to include the Encryption Token in the security header as well or not (for IssuerSerial, Thumbprint, SKI cases). Default is "false"

  • ENABLE_NONCE_CACHE (enableNonceCache) - Whether to cache UsernameToken nonces. Default is "true"

  • ENABLE_TIMESTAMP_CACHE (enableTimestampCache) - Whether to cache Timestamp Created Strings (these are only cached in conjunction with a message Signature). Default is "true"

  • ENABLE_SAML_ONE_TIME_USE_CACHE (enableSamlOneTimeUseCache) - Whether to cache SAML2 Token Identifiers, if the token contains a "OneTimeUse" Condition. Default is "true".

  • USE_2005_12_NAMESPACE (use200512Namespace) - Whether to use the 2005/12 namespace for SecureConveration + DerivedKeys, or the older namespace. The default is "true"

  • OPTIONAL_SIGNATURE_PARTS (optionalSignatureParts) - Parameter to define which parts of the request shall be signed, if they exist in the request.

  • OPTIONAL_ENCRYPTION_PARTS (optionalEncryptionParts) - Parameter to define which parts of the request shall be encrypted, if they exist in the request.

  • ENC_MGF_ALGO (encryptionMGFAlgorithm) - Defines which encryption mgf algorithm to use with the RSA OAEP Key Transport algorithm for encryption. The default is mgfsha1.

  • VALIDATOR_MAP (validatorMap) - A map of QName, Object (Validator) instances to be used to validate tokens identified by their QName.

  • NONCE_CACHE_INSTANCE (nonceCacheInstance) - A ReplayCache instance used to cache UsernameToken nonces. The default instance that is used is the EHCacheReplayCache.

  • TIMESTAMP_CACHE_INSTANCE (timestampCacheInstance) - A ReplayCache instance used to cache Timestamp Created Strings. The default instance that is used is the EHCacheReplayCache.

  • SAML_ONE_TIME_USE_CACHE_INSTANCE (samlOneTimeUseCacheInstance) - A ReplayCache instance used to cache SAML2 Token Identifier Strings (if the token contains a OneTimeUse Condition). The default instance that is used is the EHCacheReplayCache.

  • PASSWORD_ENCRYPTOR_INSTANCE (passwordEncryptorInstance) - A PasswordEncryptor instance used to decrypt encrypted passwords in Crypto properties files. The default is the JasyptPasswordEncryptor.

  • DERIVED_TOKEN_REFERENCE (derivedTokenReference) - This controls how deriving tokens are referenced.

  • DERIVED_TOKEN_KEY_ID (derivedTokenKeyIdentifier) - This controls the key identifier of Derived Tokens.

  • DERIVED_SIGNATURE_KEY_LENGTH (derivedSignatureKeyLength) - The length to use (in bytes) when deriving a key for Signature.

  • DERIVED_ENCRYPTION_KEY_LENGTH (derivedEncryptionKeyLength) - The length to use (in bytes) when deriving a key for Encryption.

Derived Key and Secure Conversation namespace change

In WSS4J 1.6.x, the default namespace used for Derived Key and Secure Conversation was the older "http://schemas.xmlsoap.org/ws/2005/02/sc" namespace. In WSS4J 2.0.0, the default namespace is now "http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512". To switch back to use the older namespace, you can set the new configuration property "USE_2005_12_NAMESPACE" to "false".

Caching changes

WSS4J 2.0.0 uses three EhCache-based caches by default for the following scenarios, to prevent replay attacks:

  • UsernameToken nonces

  • Signed Timestamps

  • SAML 2.0 OneTimeUse Assertions

If you are seeing a error about "replay attacks" after upgrade, then you may need to disable a particular cache.

RSA v1.5 Key Transport algorithm not allowed by default

WSS4J supports two key transport algorithms, RSA v1.5 and RSA-OAEP. A number of attacks exist on RSA v1.5. Therefore, you should always use RSA-OAEP as the key transport algorithm. In WSS4J 2.0.0, the RSA v1.5 Key Transport algorithm is not allowed by default (as opposed to previous versions of WSS4J, where it is allowed). If you wish to allow it, then you must set the WSHandlerConstants.ALLOW_RSA15_KEY_TRANSPORT_ALGORITHM property to "true".

InclusiveNamespaces PrefixList change

In WSS4J 1.6.x, when BSP Compliance was switched off on the outbound side, it had the effect that an InclusiveNamespaces PrefixList was not generated as a CanonicalizationMethod child of a Signature Element (as required by the BSP specification). In WSS4J 2.0.0, this is now controlled by a separate configuration tag "addInclusivePrefixes", which defaults to true.

New features available in Apache WSS4J 2.0.0

Overview of new features

Apache WSS4J 2.0.0 delivers the following major new features:

  • Support for a streaming (StAX) based WS-Security implementation that covers all of the main specifications.

  • A WS-SecurityPolicy model that can be shared between both DOM + StAX implementations.

  • Support for "real-time" WS-SecurityPolicy validation for the StAX implementation.

  • Support for the SOAP with Attachments (SWA) Profile 1.1 specification.

  • Support for caching based on EhCache.

  • Support for encrypting passwords in Crypto properties files using Jasypt.

Streaming (StAX) based WS-Security implementation

WSS4J 2.0.0 introduces a new streaming (StAX) based WS-Security implementation. Please see the dedicated page for more information.

WS-SecurityPolicy support

WSS4J 2.0.0 introduces a new WS-SecurityPolicy model as part of the "wss4j-policy" module. This model can be shared between both the DOM and StAX WS-Security implementations. Web service stacks such as Apache CXF and Apache Axis/Rampart that use WSS4J for WS-Security no longer need to maintain their own model. In this way any bug fixes to the model will get picked up by all web service stacks that rely on WSS4J.

In addition to the new WS-SecurityPolicy model, a significant new feature of WSS4J 2.0.0 is that the new streaming WS-Security implementation has the ability to perform "real-time" validation of a request against the set of applicable WS-SecurityPolicy policies. The DOM-based code in WSS4J does not have any concept of WS-SecurityPolicy, but instead processes an inbound request, and relies on the web service stack to compare the results against the applicable policies. The advantage of the streaming approach in WSS4J 2.0.0 is that bogus requests can be rejected quicker, which may help to avoid DoS based scenarios.

Support for signing and encrypting message attachments

WSS4J 2.0.0 introduces support for signing and encrypting SOAP message attachments, via the the SOAP with Attachments (SWA) Profile 1.1 specification. Please see the dedicated page for more information.

Replay Attack detection using EhCache

In WSS4J 1.6.x, a "ReplayCache" interface was introduced to cache tokens to guard against replay attacks for the following scenarios:

  • Signed Timestamps

  • UsernameToken nonces

  • SAML OneTimeUse Assertions

However, replay attack detection was not "switched on" by default in WSS4J 1.6.x. In WSS4J 2.0.x, replay attack detection is enabled by default using an implementation of the "ReplayCache" interface based on EhCache. The following configuration tags can be used to configure caching:

  • ConfigurationConstants.TIMESTAMP_CACHE_INSTANCE ("timestampCacheInstance"): This holds a reference to a ReplayCache instance used to cache Timestamp Created Strings. The default instance that is used is the EHCacheReplayCache.

  • ConfigurationConstants.ENABLE_TIMESTAMP_CACHE ("enableTimestampCache"): Whether to cache Timestamp Created Strings (these are only cached in conjunction with a message Signature). The default value is "true".

  • ConfigurationConstants.NONCE_CACHE_INSTANCE ("nonceCacheInstance"): This holds a reference to a ReplayCache instance used to cache UsernameToken nonces. The default instance that is used is the EHCacheReplayCache.

  • ConfigurationConstants.ENABLE_NONCE_CACHE ("enableNonceCache"): Whether to cache UsernameToken nonces. The default value is "true".

  • ConfigurationConstants. SAML_ONE_TIME_USE_CACHE_INSTANCE ("samlOneTimeUseCacheInstance"): This holds a reference to a ReplayCache instance used to cache SAML2 Token Identifier Strings (if the token contains a OneTimeUse Condition). The default instance that is used is the EHCacheReplayCache.

  • ConfigurationConstants.ENABLE_SAML_ONE_TIME_USE_CACHE ("enableSamlOneTimeUseCache"): Whether to cache SAML2 Token Identifiers, if the token contains a "OneTimeUse" Condition. The default value is "true".

Encrypting passwords in Crypto property files

A typical example of the contents of a Crypto properties file (for Signature creation) is as follows:

  • org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin

  • org.apache.wss4j.crypto.merlin.keystore.type=jks

  • org.apache.wss4j.crypto.merlin.keystore.password=security

  • org.apache.wss4j.crypto.merlin.keystore.alias=wss40

  • org.apache.wss4j.crypto.merlin.keystore.file=keys/wss40.jks

Note that the password used to load the keystore is in cleartext. One of the new features of Apache WSS4J 2.0.0 is the ability to instead store a (BASE-64 encoded) encrypted version of the keystore password in the Crypto properties file. A new PasswordEncryptor interface is defined to allow for the encryption/decryption of passwords. A default implementation is now provided based on Jasypt called JasyptPasswordEncryptor, which uses "PBEWithMD5AndTripleDES".

The WSPasswordCallback class has an additional "usage" called WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD, which is used to return the master password for use with the PasswordEncryptor implementation. When WSS4J is loading a Crypto implementation via a properties file, and it encounters a password encrypted in the format "ENC(encoded encrypted password)", it queries a CallbackHandler for a password via this WSPasswordCallback usage tag. It is possible to pass a custom PasswordEncryptor implementation to WSS4J via the new configuration tag ConfigurationConstants.PASSWORD_ENCRYPTOR_INSTANCE ("passwordEncryptorInstance").

Miscellaneous new features

Support was added in WSS4J 1.6.x to obtain a Kerberos ticket from a KDC (Key Distribution Center) and include it in the security header of a request, as well as to process the received token. However, there was no built-in way to extract the secret key from the ticket to secure the request. Instead it was up to the user to plug in a custom "KerberosTokenDecoder" implementation to support this behaviour. In WSS4J 2.0.0, a default KerberosTokenDecoder implementation is provided, and so WSS4J now supports signing/encrypting using Kerberos tokens by default.

A new "CustomToken" Action is defined in WSS4J 2.0.0. If this action is defined, a token (DOM Element) will be retrieved from a CallbackHandler via WSPasswordCallback.Usage.CUSTOM_TOKEN and written out as is in the security header. This provides for an easy way to write out tokens that have been retrieved out of band. Another related new feature is the ability to associate an action with a particular set of keys/algorithms. This means that it is now possible to configure two different Signature actions, that use different keys/algorithms.

Support for enforcing the Basic Security Profile (BSP) 1.1 specification was added in WSS4J 1.6.x. In WSS4J 2.0.0, it is possible to disable individual BSP Rules for a non-compliant request, instead of having to disable BSP enforcement altogether as for WSS4J 1.6.x. The RequestData class has a setIgnoredBSPRules method, that takes a list of BSPRule Objects as an argument. The BSPRule class contains a complete list of Basic Security Profile rules that are enforced in WSS4J.

WSS4J 2.0.0 now enforces the SubjectConfirmation requirements of an inbound SAML Token, instead of leaving it to the web services stack. For sender-vouches, a Signature must be present that covers both the SOAP Body and the SAML Assertion. For holder-of-key, a Signature must be present that signs some part of the SOAP request using the key information contained in the SAML Subject. Note that a Signature can be either a message or transport level Signature (i.e. using TLS is acceptable). A new configuration tag is defined that allows the user to switch off this validation if required (ConfigurationConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION - "validateSamlSubjectConfirmation").

Apache WSS4J 1.6.0 Migration Guide

This page describes the new features of WSS4J 1.6.0, and the things to be aware of when upgrading from WSS4J 1.5.x. Note that WSS4J 1.6.x has now been replaced by WSS4J 2.0.x, please see the WSS4J 2.0.0 migration guide for more information.

New features

This section describes the main new features that have been implemented in WSS4J 1.6. For more information on the changes, please click on the links. You can also review the list of JIRAs that have been fixed in WSS4J 1.6.

  • JSR-105 support: WSS4J 1.6 has been ported to use the JSR 105 API for XML Digital Signature.

  • SAML2 support: WSS4J 1.6 includes full support for creating, manipulating and parsing SAML2 assertions, via the Opensaml2 library.

  • Performance work: A general code-rewrite has been done with a focus on improving performance, e.g. the changes that have been made to processor loading.

  • Basic Security Profile 1.1 compliance: WSS4J 1.6 provides support for the BSP 1.1 specification.

  • JDK 1.5 port: The JDK 1.4 requirement of WSS4J 1.5.x has been dropped as part of this work.

  • Support for Crypto trust-stores: WSS4J 1.6 separates the concept of keystore and truststores for Crypto implementations.

  • New Validator interface: WSS4J 1.6 moves all validation of security tokens into a new Validator interface, which allows for custom validation of specific tokens.

  • Support for the Kerberos Token Profile (in WSS4J 1.6.2 and 1.6.3).

Upgrade notes

This section describes the changes that have been made in WSS4J 1.6 that will impact on an existing user of WSS4J 1.5.x. Although WSS4J 1.6 is not 100% backwards compatible with 1.5.x, a general goal for the release was to restrict the API changes to those that were strictly necessary.

  • All Axis1 dependencies have been removed. Any user wishing to use WSS4J with Axis1 must use the WSS4J 1.5.x library. As Axis1 has been replaced by Axis2, this is unlikely to be an issue.

  • A number of changes have been made to the Crypto interface. See here, here and here for an indepth explanation. In a nutshell, these changes are:

    1. The BouncyCastle crypto implementation has been removed (replaced by Merlin)

    2. A new set of Merlin "truststore" configuration tags have been added. The behaviour of the old Merlin configuration tags will work exactly the same way in WSS4J 1.6.

    3. The CA certs are now <b>not</b> loaded by default.

    4. PublicKeys (from KeyValues) are now not handled by a PublicKeyCallback, but by the Crypto implementation directly.

  • If the WSEncryptionPart used to point to an element for signature or encryption does not either store the element directly, or store the wsu:Id, all DOM Elements that match the stored localname/namespace will be processed. See the Special Topics page for more information.

  • WSS4J 1.5.x used Opensaml1 to provide extremely limited support for SAML 1 assertions. WSS4J 1.6 has been upgraded to Opensaml2, and provides far more comprehensive support for SAML. See here for more information on this. Some changes to be aware of are:

    1. The way of creating SAML assertions via a properties file has completely changed. For example, see SAML Token Test.

    2. WSS4J 1.5.x ignored (enveloped) signatures on SAML (1.1) assertions - this is no longer the case, so deployments which do not set the correct keystore/truststore config for dealing with signature verification will fail.

    3. The SAMLTokenProcessor no longer saves all tokens as an "WSConstants.ST_UNSIGNED" action. It saves tokens that do not have an enveloped signature as this action, and token which do have an enveloped signature are saved as a "WSConstants.ST_SIGNED" action.

    4. The object that is saved as part of the action above has changed, from an Opensaml1 specific Assertion object, to an AssertionWrapper instance, which is a WSS4J specific object which encapsulates an Assertion, as well as some information corresponding to signature verification, etc.

  • The way that UsernameTokens are processed has been changed. See here for more information. Some important changes are:

    1. The plaintext password case has exactly the same behaviour as the digest case. The identifier is now WSPasswordCallback.USERNAME_TOKEN and not WSPasswordCallback.USERNAME_TOKEN_UNKNOWN, and the CallbackHandler does not do any authentication, but must set the password on the callback.

    2. The custom password type case defaults to the same behaviour as the plaintext case, assuming wssConfig.getHandleCustomPasswordTypes() returns true.

    3. For the case of a username token with no password element, the default behaviour is simply to ignore it, and to store it as a new result of type WSConstants.UT_NOPASSWORD.

  • Some changes have been made to the WSPasswordCallback identifiers, used to obtain passwords for various actions. For more information see here. In a nutshell, these changes consist of:

    1. The WSPasswordCallback KEY_NAME, USERNAME_TOKEN_UNKNOWN and WSPasswordCallback.ENCRYPTED_KEY_TOKEN identifiers have been removed.

    2. CUSTOM_TOKEN is not longer used in the processors to get a secret key.

    3. SECRET_KEY is a new identifier for finding secret keys. It replaces the occasionally incorrect use of CUSTOM_TOKEN, as well as KEY_NAME and ENCRYPTED_KEY_TOKEN.

  • Timestamp validation and signature trust verification is not done by the WSHandler implementation any more, but is performed when the security header is processed.

WSS4J configuration

This section describes how to use configure Apache WSS4J. This page only applies to WSS4J 2.x, and 1.6.x, a lot of the properties have changed since WSS4J 1.5.x.

Crypto properties

Apache WSS4J uses the Crypto interface to get keys and certificates for encryption/decryption and for signature creation/verification. WSS4J ships with three implementations:

  • Merlin: The standard implementation, based around two JDK keystores for key/cert retrieval, and trust verification.

  • CertificateStore: Holds an array of X509 Certificates. Can only be used for encryption and signature verification.

  • MerlinDevice: Based on Merlin, allows loading of keystores using a null InputStream - for example on a smart-card device.

For more information on the Crypto implementations see the Special Topics page. It is possible to instantiate a Crypto implementation directly, but it can also be loaded via a properties file. For Apache WSS4J 2.0.0 onwards, the property names ${PREFIX} below is "org.apache.wss4j.crypto". For Apache WSS4J 1.6.x, the property names ${PREFIX} below is "org.apache.ws.security.crypto". WSS4J 2.0.0 onwards will also accept the older ${PREFIX} value. The property values for the standard Merlin implementation are as follows:

General properties

  • ${PREFIX}.provider - WSS4J specific provider used to create Crypto instances. Defaults to "org.apache.wss4j.common.crypto.Merlin".

  • ${PREFIX}.merlin.x509crl.file - The location of an (X509) CRL file to use.

Merlin Keystore Properties

  • ${PREFIX}.merlin.keystore.provider - The provider used to load keystores. Defaults to installed provider.

  • ${PREFIX}.merlin.cert.provider - The provider used to load certificates. Defaults to keystore provider.

  • ${PREFIX}.merlin.keystore.file - The location of the keystore

  • ${PREFIX}.merlin.keystore.password - The password used to load the keystore. Default value is "security".

  • ${PREFIX}.merlin.keystore.type - Type of keystore. Defaults to: java.security.KeyStore.getDefaultType())

  • ${PREFIX}.merlin.keystore.alias - The default keystore alias to use, if none is specified.

  • ${PREFIX}.merlin.keystore.private.password - The default password used to load the private key.

Merlin TrustStore properties

  • ${PREFIX}.merlin.load.cacerts - Whether or not to load the CA certs in ${java.home}/lib/security/cacerts (default is false)

  • ${PREFIX}.merlin.truststore.file - The location of the truststore

  • ${PREFIX}.merlin.truststore.password - The truststore password. Defaults to "changeit".

  • ${PREFIX}.merlin.truststore.type - The truststore type. Defaults to: java.security.KeyStore.getDefaultType().

  • ${PREFIX}.merlin.truststore.provider - WSS4J 2.1.5 The provider used to load truststores. By default it’s the same as the keystore provider. Set to an empty value to force use of the JRE’s default provider.

SAML properties

WSS4J 1.6.x only Apache WSS4J 1.6.x uses the SAMLIssuer interface to configure the creation and signing of a SAML Assertion. In Apache WSS4J 2.0.0, the SAMLIssuer functionality has been moved to the SAMLCallback, so that the CallbackHandler used to create a SAML Assertion is responsible for all of the signing configuration as well.

WSS4J 1.6.x ships with a default "SAMLIssuerImpl" implementation. It is possible to instantiate a SAMLIssuer implementation directly, but it can also be loaded via a properties file. The property values are as follows:

SAMLIssuer properties

  • org.apache.ws.security.saml.issuerClass - The SAML Issuer implementation (defaults to "org.apache.ws.security.saml.SAMLIssuerImpl").

  • org.apache.ws.security.saml.issuer.cryptoProp.file - The crypto properties file corresponding to the issuer crypto instance, if the assertion is to be signed.

  • org.apache.ws.security.saml.issuer.key.name - The KeyStore alias for the issuer key.

  • org.apache.ws.security.saml.issuer.key.password - The KeyStore password for the issuer key.

  • org.apache.ws.security.saml.issuer - The issuer name

  • org.apache.ws.security.saml.issuer.sendKeyValue - Whether to send the key value or the X509Certificate. Default is "false".

  • org.apache.ws.security.saml.issuer.signAssertion - Whether the SAMLIssuer implementation will sign the assertion or not. Default is "false".

  • org.apache.ws.security.saml.callback - The name of the SAML CallbackHandler implementation used to populate the SAML Assertion.

Configuration tags

Apache WSS4J provides a set of configuration tags that can be used to configure both the DOM-based and StAX-based (WSS4J 2.0.0 onwards) outbound and inbound processing. As both DOM and StAX code are very similar, both approaches share a set of common configuration tags given in ConfigurationConstants. Note that the WSS4J 1.6.x configuration class (WSHandlerConstants) extends this class in WSS4J 2.0.0, so there is no need to change any configuration code when upgrading.

The configuration tags for Actions are as follows:

Action configuration tags

  • ACTION (action) - The action to perform, e.g. ConfigurationConstants.TIMESTAMP

  • NO_SECURITY (NoSecurity) - Do not perform any action, do nothing. Only applies to DOM code.

  • WSS4J 2.0.0 USERNAME_TOKEN_SIGNATURE (UsernameTokenSignature) - Perform a UsernameTokenSignature action.

  • USERNAME_TOKEN (UsernameToken) - Perform a UsernameToken action.

  • USERNAME_TOKEN_NO_PASSWORD (UsernameTokenNoPassword) - Used on the receiving side to specify a UsernameToken with no password

  • SAML_TOKEN_UNSIGNED (SAMLTokenUnsigned) - Perform an unsigned SAML Token action.

  • SAML_TOKEN_SIGNED (SAMLTokenSigned) - Perform a signed SAML Token action.

  • SIGNATURE (Signature) - Perform a signature action.

  • ENCRYPT (Encrypt) - Perform an encryption action.

  • TIMESTAMP (Timestamp) - Perform a Timestamp action.

  • WSS4J 2.0.0 SIGNATURE_DERIVED (SignatureDerived) - Perform a Signature action with derived keys.

  • WSS4J 2.0.0 ENCRYPT_DERIVED (EncryptDerived) - Perform a Encryption action with derived keys.

  • WSS4J 2.0.0 SIGNATURE_WITH_KERBEROS_TOKEN (SignatureWithKerberosToken) - Perform a Signature action with a kerberos token. Only for StAX code.

  • WSS4J 2.0.0 ENCRYPT_WITH_KERBEROS_TOKEN (EncryptWithKerberosToken) - Perform a Encryption action with a kerberos token. Only for StAX code.

  • WSS4J 2.0.0 KERBEROS_TOKEN (KerberosToken) - Add a kerberos token. Only for StAX code.

  • WSS4J 2.0.0 CUSTOM_TOKEN (CustomToken) - Add a "Custom" token from a CallbackHandler

  • WSS4J 1.6.x only SIGN_WITH_UT_KEY (UsernameTokenSignature) - Perform a .NET specific signature using a Username Token action.

WSHandler User configuration tags

The configuration tags for WSHandler user properties are as follows:

  • ACTOR ("actor") - The actor or role name of the wsse:Security header.

  • USER ("user") - The user’s name. Consult the Javadoc for an explanation of this property.

  • ENCRYPTION_USER ("encryptionUser") - The user’s name for encryption. Consult the Javadoc for an explanation of this property.

  • SIGNATURE_USER ("signatureUser") - The user’s name for signature. Consult the Javadoc for an explanation of this property.

  • USE_REQ_SIG_CERT ("useReqSigCert") - A special value for ENCRYPTION_USER. Consult the Javadoc for an explanation of this property.

Callback class and Property File configuration tags

The configuration tags for callback class and property file configuration are summarised here:

  • PW_CALLBACK_CLASS (passwordCallbackClass) - The CallbackHandler implementation class used to obtain passwords.

  • PW_CALLBACK_REF (passwordCallbackRef) - The CallbackHandler implementation object used to obtain passwords.

  • SAML_CALLBACK_CLASS (samlCallbackClass) - The CallbackHandler implementation class used to construct SAML Assertions.

  • SAML_CALLBACK_REF (samlCallbackRef) - The CallbackHandler implementation object used to construct SAML Assertions.

  • WSS4J 1.6.x only ENC_CALLBACK_CLASS (embeddedKeyCallbackClass) - The CallbackHandler implementation class used to get the key associated with a key name.

  • WSS4J 1.6.x only ENC_CALLBACK_REF (embeddedKeyCallbackRef) - The CallbackHandler implementation object used to get the key associated with a key name.

  • SIG_PROP_FILE (signaturePropFile) - The path of the crypto property file to use for Signature.

  • SIG_PROP_REF_ID (signaturePropRefId) - The String ID that is used to store a reference to the Crypto object or the Crypto Properties object for Signature.

  • WSS4J 2.0.0 SIG_VER_PROP_FILE (signatureVerificationPropFile) - The path of the crypto property file to use for Signature verification.

  • WSS4J 2.0.0 SIG_VER_PROP_REF_ID (signatureVerificationPropRefId) - The String ID that is used to store a reference to the Crypto object or the Crypto Properties object for Signature verification.

  • DEC_PROP_FILE (decryptionPropFile) - The path of the crypto property file to use for Decryption.

  • DEC_PROP_REF_ID (decryptionPropRefId) - The String ID that is used to store a reference to the Crypto object or the Crypto Properties object for decryption.

  • ENC_PROP_FILE (encryptionPropFile) - The path of the crypto property file to use for encryption.

  • ENC_PROP_REF_ID (encryptionPropRefId) - The String ID that is used to store a reference to the Crypto object or the Crypto Properties object for encryption.

  • SAML_PROP_FILE (samlPropFile) - The path of the property file to use for creating SAML Assertions.

Boolean configuration tags

The configuration tags for properties that are configured via a boolean parameter (i.e. "true" or "false") are as follows:

  • ENABLE_SIGNATURE_CONFIRMATION (enableSignatureConfirmation) - Whether to enable signature confirmation or not. Default is "false".

  • MUST_UNDERSTAND (mustUnderstand) - Set the outbound MustUnderstand flag or not. Default is "true".

  • IS_BSP_COMPLIANT (isBSPCompliant) - Whether or not to ensure compliance with the BSP 1.1 spec. Default is "true".

  • WSS4J 2.0.0 ADD_INCLUSIVE_PREFIXES (addInclusivePrefixes) - Whether to add an InclusiveNamespaces PrefixList as a CanonicalizationMethod child when generating Signatures using WSConstants.C14N_EXCL_OMIT_COMMENTS. Default is "true".

  • WSS4J 2.0.0 ADD_USERNAMETOKEN_NONCE (addUsernameTokenNonce) - Whether to add a Nonce Element to a UsernameToken (for plaintext). Default is "false"

  • WSS4J 2.0.0 ADD_USERNAMETOKEN_CREATED (addUsernameTokenCreated) - Whether to add a Created Element to a UsernameToken (for plaintext). Default is "false"

  • HANDLE_CUSTOM_PASSWORD_TYPES (handleCustomPasswordTypes) - Whether to allow non-standard password types in a UsernameToken. Default is "false".

  • WSS4J 1.6.x only PASSWORD_TYPE_STRICT (passwordTypeStrict) - Whether to enable strict Username Token password type handling. Default is "false".

  • WSS4J 2.0.0 ALLOW_USERNAMETOKEN_NOPASSWORD (allowUsernameTokenNoPassword) - Whether a UsernameToken with no password element is allowed. Default is "false".

  • REQUIRE_SIGNED_ENCRYPTED_DATA_ELEMENTS (requireSignedEncryptedDataElements) - Whether the engine needs to enforce EncryptedData elements are in a signed subtree of the document. Default is "false".

  • WSS4J 1.6.x only USE_DERIVED_KEY (useDerivedKey) - Whether to use the standard UsernameToken Key Derivation algorithm. Default is "true".

  • ALLOW_NAMESPACE_QUALIFIED_PASSWORD_TYPES (allowNamespaceQualifiedPasswordTypes) - Whether (wsse) namespace qualified password types are accepted when processing UsernameTokens. Default is "false".

  • ENABLE_REVOCATION (enableRevocation) - Whether to enable Certificate Revocation List (CRL) checking when verifying trust in a certificate. Default is "false".

  • USE_ENCODED_PASSWORDS (useEncodedPasswords) - Set whether to treat passwords as binary values for Username Tokens. Default is "false". DOM code only.

  • USE_SINGLE_CERTIFICATE (useSingleCertificate) - Whether to use a single certificate or a whole certificate chain to construct a BinarySecurityToken. Default is "true".

  • USE_DERIVED_KEY_FOR_MAC (useDerivedKeyForMAC) - Whether to use the Username Token derived key for a MAC. Default is "true".

  • TIMESTAMP_PRECISION (precisionInMilliseconds) - Set whether outbound timestamps have precision in milliseconds. Default is "true".

  • TIMESTAMP_STRICT (timestampStrict) - Set whether to enable strict Timestamp handling, i.e. throw an exception if the current receiver time is past the Expires time of the Timestamp. Default is "true".

  • WSS4J 2.0.4/2.1.0 REQUIRE_TIMESTAMP_EXPIRES (requireTimestampExpires) - Set the value of this parameter to true to require that a Timestamp must have an "Expires" Element. The default is "false".

  • ENC_SYM_ENC_KEY (encryptSymmetricEncryptionKey) - Set whether to encrypt the symmetric encryption key or not. Default is "true".

  • WSS4J 2.0.0 ALLOW_RSA15_KEY_TRANSPORT_ALGORITHM (allowRSA15KeyTransportAlgorithm) - Whether to allow the RSA v1.5 Key Transport Algorithm or not. Default is "false".

  • WSS4J 2.0.0 VALIDATE_SAML_SUBJECT_CONFIRMATION (validateSamlSubjectConfirmation) - Whether to validate the SubjectConfirmation requirements of a received SAML Token (sender-vouches or holder-of-key). Default is "true".

  • WSS4J 2.0.0 INCLUDE_SIGNATURE_TOKEN (includeSignatureToken) - Whether to include the Signature Token in the security header as well or not (for IssuerSerial, Thumbprint, SKI cases). Default is "false"

  • WSS4J 2.0.0 INCLUDE_ENCRYPTION_TOKEN (includeEncryptionToken) - Whether to include the Encryption Token in the security header as well or not (for IssuerSerial, Thumbprint, SKI cases). Default is "false"

  • WSS4J 2.0.0 USE_2005_12_NAMESPACE (use200512Namespace) - Whether to use the 2005/12 namespace for SecureConveration + DerivedKeys, or the older namespace. The default is "true"

  • WSS4J 2.1.2/2.0.5 GET_SECRET_KEY_FROM_CALLBACK_HANDLER (getSecretKeyFromCallbackHandler) - Whether to get a secret key from a CallbackHandler or not for encryption only. The default is false. If set to true WSS4J attempts to get the secret key from the CallbackHandler instead of generating a random key internally.

  • WSS4J 2.1.2/2.0.5 STORE_BYTES_IN_ATTACHMENT (storeBytesInAttachment) - Whether to store bytes (CipherData or BinarySecurityToken) in an attachment. The default is false, meaning that bytes are BASE-64 encoded and "inlined" in the message. Setting this to true is more efficient, as it means that the BASE-64 encoding step can be skipped. For this to work, a CallbackHandler must be set on RequestData that can handle attachments.

  • WSS4J 2.1.2/2.0.5 EXPAND_XOP_INCLUDE_FOR_SIGNATURE (expandXOPIncludeForSignature) - (Deprecated in 2.2.0). Whether to expand xop:Include Elements encountered when verifying a Signature. The default is true, meaning that the relevant attachment bytes are BASE-64 encoded and inserted into the Element. This ensures that the actual bytes are signed, and not just the reference.

  • WSS4J 2.2.0 EXPAND_XOP_INCLUDE (expandXOPInclude) - Whether to search for and expand xop:Include Elements for encryption and signature (on the outbound side) or for signature verification (on the inbound side). The default is false on the outbound side and true on the inbound side. What this means on the inbound side, is that the relevant attachment bytes are BASE-64 encoded and inserted into the Element. This ensures that the actual bytes are signed, and not just the reference.

Non-boolean configuration tags

The configuration tags for properties that are configured via a non-boolean parameter are as follows:

  • PASSWORD_TYPE (passwordType) - The encoding of the password for a Username Token. The default is WSConstants.PW_DIGEST.

  • WSS4J 1.6.x only ENC_KEY_NAME (embeddedKeyName) - The text of the key name to be sent in the KeyInfo for encryption

  • WSS4J 1.6.x only ADD_UT_ELEMENTS (addUTElements) - Additional elements to add to a Username Token, i.e. "nonce" and "created".

  • SIG_KEY_ID (signatureKeyIdentifier) - The key identifier type to use for signature. The default is "IssuerSerial".

  • SIG_ALGO (signatureAlgorithm) - The signature algorithm to use. The default is set by the data in the certificate.

  • SIG_DIGEST_ALGO (signatureDigestAlgorithm) - The signature digest algorithm to use. The default is SHA-1.

  • SIG_C14N_ALGO (signatureC14nAlgorithm) - Defines which signature c14n (canonicalization) algorithm to use. The default is: "http://www.w3.org/2001/10/xml-exc-c14n#".

  • WSS4J 1.6.x only WSE_SECRET_KEY_LENGTH (wseSecretKeyLength) - The length of the secret (derived) key to use for the WSE UT_SIGN functionality.

  • SIGNATURE_PARTS (signatureParts) - Parameter to define which parts of the request shall be signed. The SOAP body is signed by default.

  • WSS4J 2.0.0 OPTIONAL_SIGNATURE_PARTS (optionalSignatureParts) - Parameter to define which parts of the request shall be signed, if they exist in the request.

  • DERIVED_KEY_ITERATIONS (derivedKeyIterations) - The number of iterations to use when deriving a key from a Username Token. The default is 1000.

  • ENC_KEY_ID (encryptionKeyIdentifier) - The key identifier type to use for encryption. The default is "IssuerSerial".

  • ENC_SYM_ALGO (encryptionSymAlgorithm) - The symmetric encryption algorithm to use. The default is AES-128.

  • ENC_KEY_TRANSPORT (encryptionKeyTransportAlgorithm) - The algorithm to use to encrypt the generated symmetric key. The default is RSA-OAEP.

  • ENC_DIGEST_ALGO (encryptionDigestAlgorithm) - The encryption digest algorithm to use with the RSA-OAEP key transport algorithm. The default is SHA-1.

  • ENCRYPTION_PARTS (encryptionParts) - Parameter to define which parts of the request shall be encrypted. The SOAP body is encrypted in "Content" mode by default.

  • WSS4J 2.0.0 OPTIONAL_ENCRYPTION_PARTS (optionalEncryptionParts) - Parameter to define which parts of the request shall be encrypted, if they exist in the request.

  • WSS4J 2.0.0 ENC_MGF_ALGO (encryptionMGFAlgorithm) - Defines which encryption mgf algorithm to use with the RSA OAEP Key Transport algorithm for encryption. The default is mgfsha1.

  • TTL_TIMESTAMP (timeToLive) - The time difference between creation and expiry time in seconds in the WSS Timestamp. The default is "300".

  • TTL_FUTURE_TIMESTAMP (futureTimeToLive) - The time in seconds in the future within which the Created time of an incoming Timestamp is valid. The default is "60".

  • TTL_USERNAMETOKEN (utTimeToLive) - The time difference between creation and expiry time in seconds in the WSS UsernameToken created element. The default is "300".

  • TTL_FUTURE_USERNAMETOKEN (utFutureTimeToLive) - The time in seconds in the future within which the Created time of an incoming UsernameToken is valid. The default is "60".

  • SIG_SUBJECT_CERT_CONSTRAINTS (sigSubjectCertConstraints) - A String (separated by the value specified for SIG_CERT_CONSTRAINTS_SEPARATOR) of regular expressions which will be applied to the subject DN of the certificate used for signature validation, after trust verification of the certificate chain associated with the certificate.

  • SIG_ISSUER_CERT_CONSTRAINTS (sigIssuerCertConstraints) - A String (separated by the value specified for SIG_CERT_CONSTRAINTS_SEPARATOR) of regular expressions which will be applied to the issuer DN of the certificate used for signature validation, after trust verification of the certificate chain associated with the certificate.

  • WSS4J 2.2.3 SIG_CERT_CONSTRAINTS_SEPARATOR (sigCertConstraintsSeparator) - The separator that is used to parse certificate constraints configured in the SIG_SUBJECT_CERT_CONSTRAINTS and SIG_ISSUER_CERT_CONSTRAINTS configuration tags. The default is ",".

  • WSS4J 2.0.0 VALIDATOR_MAP (validatorMap) - A map of QName, Object (Validator) instances to be used to validate tokens identified by their QName.

  • WSS4J 2.0.0 NONCE_CACHE_INSTANCE (nonceCacheInstance) - A ReplayCache instance used to cache UsernameToken nonces. The default instance that is used is the EHCacheReplayCache.

  • WSS4J 2.0.0 TIMESTAMP_CACHE_INSTANCE (timestampCacheInstance) - A ReplayCache instance used to cache Timestamp Created Strings. The default instance that is used is the EHCacheReplayCache.

  • WSS4J 2.0.0 SAML_ONE_TIME_USE_CACHE_INSTANCE (samlOneTimeUseCacheInstance) - A ReplayCache instance used to cache SAML2 Token Identifier Strings (if the token contains a OneTimeUse Condition). The default instance that is used is the EHCacheReplayCache.

  • WSS4J 2.0.0 PASSWORD_ENCRYPTOR_INSTANCE (passwordEncryptorInstance) - A PasswordEncryptor instance used to decrypt encrypted passwords in Crypto properties files. The default is the JasyptPasswordEncryptor.

  • WSS4J 2.0.0 DERIVED_TOKEN_REFERENCE (derivedTokenReference) - This controls how deriving tokens are referenced.

  • WSS4J 2.0.0 DERIVED_TOKEN_KEY_ID (derivedTokenKeyIdentifier) - This controls the key identifier of Derived Tokens.

  • WSS4J 2.0.0 DERIVED_SIGNATURE_KEY_LENGTH (derivedSignatureKeyLength) - The length to use (in bytes) when deriving a key for Signature.

  • WSS4J 2.0.0 DERIVED_ENCRYPTION_KEY_LENGTH (derivedEncryptionKeyLength) - The length to use (in bytes) when deriving a key for Encryption.

KeyIdentifier values

The configuration values for setting the KeyIdentifiers for signature or encryption are shown below. For an in depth explanation with examples, see this blog entry.

  • DirectReference

  • IssuerSerial

  • X509KeyIdentifier

  • SKIKeyIdentifier

  • EmbeddedKeyName

  • Thumbprint

  • EncryptedKeySHA1

  • KeyValue

  • WSS4J 2.0.0 KerberosSHA1

Streaming (StAX) WS-Security support in Apache WSS4J™ 2.0.0

Overview of new features

WSS4J 2.0.0 introduces a streaming (StAX-based) WS-Security implementation to complement the existing DOM-based implementation. The DOM-based implementation is quite performant and flexible, but suffers from having to read the entire XML tree into memory. For large SOAP requests this can have a detrimental impact on performance. In addition, for web services stacks such as Apache CXF which are streaming-based, it carries an additional performance penalty of having to explicitly convert the request stream to a DOM Element.

The new StAX-based WS-Security implementation does not read the request into memory, and hence uses far less memory for large requests. It is also more performant in certain circumstances. The StAX-based code offers largely the same functionality as that available as part of the DOM code, and is configured in mostly the same way (via configuration tags that are shared between both stacks). It does not offer the low-level API available in the DOM code to individually construct various WS-Security tokens, but instead must be used by specifying various actions to perform.

As of the time of writing, Apache CXF is the only web services stack to integrate the new WS-Security streaming functionality. To switch to use the streaming code for the manual "Action" based approach, simply change the outbound and inbound interceptors as follows:

  • "org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" to "org.apache.cxf.ws.security.wss4j.WSS4JStaxOutInterceptor".

  • "org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" to "org.apache.cxf.ws.security.wss4j.WSS4JStaxInInterceptor".

For the WS-SecurityPolicy based approach of configuring WS-Security, simply set the JAX-WS property SecurityConstants.ENABLE_STREAMING_SECURITY ("ws-security.enable.streaming") to "true".

Limitations of the streaming WS-Security implementation

The new streaming implementation in WSS4J 2.0.0 meets the vast majority of the most common use-cases. However, it does not support everything that the DOM implementation supports. The limitations are:

  • XPath evaluation is not supported apart from certain simple expressions. XPath evaluations are used with WS-SecurityPolicy RequiredElements, SignedElements, (Content)EncryptedElements. XPath expressions that point directly to the element are supported, e.g. /soap:Envelope/soap:Header/wsa:To. See WSS-445.

  • WS-SecurityPolicy "Strict" Layout validation is not enforced. This includes enforcing whether a Timestamp is first or last. See WSS-444.

  • A SymmetricBinding policy with a ProtectTokens assertion is not supported. See WSS-456.

  • The combination of EncryptBeforeSigning + EncryptSignature policies are not supported. See WSS-464.

  • Deriving keys from Username Tokens (Endorsing Username Tokens) are not supported.

  • Endorsing tokens don’t work with Symmetric + Asymmetric binding on the client side, unless the endorsing token is a SAML or IssuedToken.

  • Derived Endorsing Tokens are not supported on the client side.

Securing message attachments

WSS4J 2.0.0 introduces support for signing and encrypting SOAP message attachments, via the the SOAP with Attachments (SWA) Profile 1.1 specification. There is no support in WSS4J 1.6.x for signing or encrypting message attachments. Attachments can be signed and encrypted in WSS4J via either the "action"-based approach or via WS-SecurityPolicy, as covered in the sections below.

The message attachment streams must be supplied to WSS4J for signature/encryption via a CallbackHandler approach. An AttachmentRequestCallback Object is used to retrieve either a particular Attachment (on the receiving side), or all attachments (on the sending side). The user must implement a CallbackHandler that sets a list of Attachments matching this request on the Callback. Correspondingly, there is also a AttachmentResponseCallback, which represents the secured/processed Attachment.

The good news is that if you are using Apache CXF then all of this is taken care of automatically by a CallbackHandler that retrieves and sets CXF message attachments. Therefore if you are using CXF then you can sign/encrypt message attachments just by setting the configuration detailed in the next couple of sections.

Securing message attachments via the action approach

With the "action" approach to using WSS4J, the user specifies the parts to sign or encrypt via the following configuration tags:

  • ConfigurationConstants.SIGNATURE_PARTS ("signatureParts")

  • ConfigurationConstants.ENCRYPTION_PARTS ("encryptionParts")

The value of these tags is a String in a special format that looks something like "{Content}{http://example.org/paymentv2}CreditCard" ({modifier}{namespace}localname). In WSS4J 2.0.0, it is possible to sign/encrypt all of the attachments by specifying the following as part of signatureParts/encryptionParts: "{}cid:Attachments;". Note that this signs or encrypts all of the attachments, it is not possible to only sign/encrypt individual attachments.

Securing message attachments via WS-SecurityPolicy

An easier way to use WSS4J is in conjunction with a web services stack such as Apache CXF and a WS-SecurityPolicy-based policy. It is possible to sign/encrypt all attachments by adding a "sp:Attachments" policy as a child of either a "sp:SignedParts" or "sp:EncryptedParts" policy. In addition, the "sp:Attachments" policy for SignedParts only has two optional child policies called "sp13:ContentSignatureTransform" and "sp13:AttachmentCompleteSignatureTransform", which dictate whether the attachment headers are included or not in the Signature.

WSS4J Special Topics

This section discusses various topics regarding usage of WSS4J. See the Using Apache WSS4J page for web stack-specific usage notes.

Crypto Interface

WSS4J uses the Crypto interface to provide a pluggable way of retrieving and converting certificates, verifying trust on certificates etc. Three implementations are provided out of the box by WSS4J:

  • Merlin: The standard implementation, based around two JDK keystores for key/cert retrieval, and trust verification.

  • CertificateStore: Holds an array of X509 Certificates. Can only be used for encryption and signature verification.

  • MerlinDevice: Based on Merlin, allows loading of keystores using a null InputStream - for example on a smart-card device.

Typically, a Crypto implementation is loaded and configured via a Crypto properties file. This tells WSS4J what Crypto implementation to load, as well as implementation-specific properties such as a keystore location, password, default alias to use, etc. A typical example of the contents of a Crypto properties file for Signature creation is as follows:

  • org.apache.wss4j.crypto.provider=org.apache.wss4j.common.crypto.Merlin

  • org.apache.wss4j.crypto.merlin.keystore.type=jks

  • org.apache.wss4j.crypto.merlin.keystore.password=security

  • org.apache.wss4j.crypto.merlin.keystore.alias=wss40

  • org.apache.wss4j.crypto.merlin.keystore.file=keys/wss40.jks

Note that in WSS4J 2.0.0 the "org.apache.ws.security.crypto" prefix used previously is now "org.apache.wss4j.crypto", however both prefixes are accepted by the code. For WSS4J 1.6.X and 1.5.X, you must use the "org.apache.ws.security.crypto" prefix.

Verifying Public Keys

In WSS4J 1.5.x, trust validation of public keys involved construction of a PublicKeyCallback instance, passing it the PublicKey object, and invoking the CallbackHandler. It then called a "isVerified" method on the Callback to check to see whether the CallbackHandler had verified the PublicKey or not. The CallbackHandler implementation needed to call the "verifyTrust" method on the PublicKeyCallback, passing in a KeyStore object. This method iterates through each Certificate in the KeyStore, and checks to see whether the PublicKeys match.

In WSS4J 1.6.x, trust validation of public keys was moved from a WSS4J 1.5’s PublicKeyCallback instance to the Crypto interface, where the argument is now a PublicKey object. In this way, validation is done using the same interface as for trust validation for Certificates, and the end-user has no need to consider the special-case of verifying public keys in the CallbackHandler, as it is taken care of internally by WSS4J.

Introducing Validators

WSS4J 1.6 introduces the concept of a Validator, for validating credentials that have been processed by a Processor instance.

An inbound security header is processed by WSS4J by iterating through each child element of the header, and by calling the appropriate Processor implementation to deal with each element. In WSS4J 1.5.x, some processors perform validation on the received token (e.g. UsernameTokens), whereas others store the processing results for later verification by third-party WS-Handler implementations (e.g. Timestamp verification, Certificate trust verification). There are some problems with this approach:

  • It is not consistent, some processors perform validation, others do not.

  • There is a potential security hole, in that it is assumed third-party code will know to validate the credentials that the WSS4J processors do not validate.

  • WSS4J will continue to process the rest of the security header even if the Timestamp is invalid, or the certificate non-trusted, which could lead to denial-of-service attacks.

  • There is no separation of concerns between processing the token and validating the token. If you want to change how the token is validated, you must replace the processor instance.

WSS4J 1.6 has moved Timestamp verification and certificate trust validation back into the processing of the security header, thus solving the first three points above. The fourth point is met by the new concept of Validators, as well as some changes to the way Processors and CallbackHandler implementations are used in WSS4J 1.6.

In WSS4J 1.5.x, CallbackHandler implementations are used in different ways by different processors, sometimes they are expected to verify a password (as for processing UsernameTokens), and other times they are expected to supply a password (as for decryption). In WSS4J 1.6, CallbackHandler implementations are only expected to supply a password (if it exists) to the processors. The Processor implementations do not perform any validation of the security token, instead they package up the processed token, along with any (password) information extracted from the CallbackHandler, and hand it off to a Validator implementation for Validation.

The Processor implementations get the specific Validator implementation to use via the RequestData parameter, which in turn asks a WSSConfig object for the Validator implementation. If the Validator is null, then no Validation is performed on the received token. The Processor then stores the received token as normal. WSS4J 1.6 comes with several default Validators, which are:

  • NoOpValidator: Does no processing of the credential

  • TimestampValidator: Validates a Timestamp

  • UsernameTokenValidator: Validates a UsernameToken

  • SignatureTrustValidator: Verifies trust in a signature

  • SamlAssertionValidator: Checks some HOK requirements on a SAML Assertion, and verifies trust on the (enveloped) signature.

There are some additional WSSecurityEngineResult constants that pertain to the Validator implementations:

  • TAG_VALIDATED_TOKEN: Indicates that the token corresponding to this result has been validated by a Validator implementation. Some of the processors do not have a default Validator implementation.

  • TAG_TRANSFORMED_TOKEN: A Validator implementation may transform a credential (into a SAML Assertion) as a result of Validation. This tag holds a reference to an AssertionWrapper instance, that represents a transformed version of the validated credential.

To validate an inbound UsernameToken in some custom way, simply associate the NoOpValidator with the UsernameToken QName in the WSSConfig of the RequestData object used to supply context information to the processors. After WSS4J has finished processing the security header, then extract the WSSecurityEngineResult instance corresponding to the WSConstants.UT action, and perform some custom validation on the token.

To validate plaintext passwords against a directory store, rather than have the CallbackHandler set the password: Simply @Override the verifyPlaintextPassword(UsernameToken usernameToken) method in the validator. By simply plugging in a validator on the UsernameTokenProcessor (such as the NoOpValidator), it is possible to do any kind of custom validation (or none at all) on the token.

An example of how to add a custom Validator implementation is the STSTokenValidator in CXF. The STSTokenValidator tries to validate a received SAML Assertion locally, and if that fails, it dispatches it to a Security Token Service (STS) via the WS-Trust interface for validation. It also supports validating a UsernameToken and BinarySecurityToken in the same manner. The SecurityConstants class defines some configuration tags for specifying a custom validator for inbound SAML1, SAML2, UsernameToken, BinarySecurityToken, Signature and Timestamps. The STSTokenValidator can be configured by associating it with the appropriate configuration tag.

Specifying elements to sign or encrypt

The signature and encryption creation code in WSS4J uses the WSEncryptionPart class to find DOM elements to sign and encrypt. There are a number of minor changes to how elements are located from a WSEncryptionPart in WSS4J 1.6:

  1. WSEncryptionPart now stores an optional DOM element, which will be used as the element to sign/encrypt if it is non-null.

  2. Failing this, it finds the SOAP body and compares the wsu:Id with the stored Id, or if there is no stored Id in WSEncryptionPart, it checks the stored localname/namespace.

  3. Failing this, if the stored Id in WSEncryptionPart is not null, it tries to find the first element in the SOAP envelope that has a matching wsu:Id.

  4. If the stored Id is null, it tries to find all DOM Elements that match the stored localname/namespace.

WSEncryptionPart is intended to refer to a single Element for encryption/signature. However, as a localname/namespace is not necessarily unique, point 4 will return all matching Elements. An important implication of the order of the steps given above, is that client code should set the DOM element on the WSEncryptionPart if it is accessible, and if not, it should set the wsu:Id. Otherwise, a localname/namespace (which is not referring to the SOAP Body) will result in a traversal of the DOM tree.

The DOM element(s) that is(are) found are stored for retrieval, so that we don’t need to traverse the SOAP envelope multiple times, when e.g. doing an STR Transform, or for element location in the XML Security code.

WSPasswordCallback identifiers

The WSPasswordCallback class defines a set of integers which correspond to usage instructions for the CallbackHandler. In WSS4J 1.6, the following WSPasswordCallback identifiers are used:

  • WSPasswordCallback.DECRYPT - DECRYPT usage is used when the calling code needs a password to get the private key of this identifier (alias) from a keystore. This is only used for the inbound case of decrypting a session (symmetric) key, and not for the case of getting a private key to sign the message. The CallbackHandler must set the password via the setPassword(String) method.

  • WSPasswordCallback.USERNAME_TOKEN - USERNAME_TOKEN usage is used to obtain a password for either creating a Username Token (whether plaintext or digest), or for validating it. It is also used for the case of deriving a key from a Username Token. The CallbackHandler must set the password via the setPassword(String) method.

  • WSPasswordCallback.SIGNATURE - SIGNATURE usage is used on the outbound side only, to get a password to get the private key of this identifier (alias) from a keystore. The CallbackHandler must set the password via the setPassword(String) method.

  • WSPasswordCallback.SECURITY_CONTEXT_TOKEN - SECURITY_CONTEXT_TOKEN usage is for the case of when we want the CallbackHandler to supply the key associated with a SecurityContextToken. The CallbackHandler must set the key via the setKey(byte[]) method.

  • WSPasswordCallback.CUSTOM_TOKEN - CUSTOM_TOKEN usage is used for the case that we want the CallbackHandler to supply a token as a DOM Element. For example, this is used for the case of a reference to a SAML Assertion or Security Context Token that is not in the message. The CallbackHandler must set the token via the setCustomToken(Element) method.

  • WSPasswordCallback.SECRET_KEY - SECRET_KEY usage is used for the case that we want to obtain a secret key for encryption or signature on the outbound side, or for decryption or verification on the inbound side. The CallbackHandler must set the key via the setKey(byte[]) method.

In WSS4J 2.0, the following additional WSPasswordCallback identifier is:

  • WSPasswordCallback.PASSWORD_ENCRYPTOR_PASSWORD - PASSWORD_ENCRYPTOR_PASSWORD usage is used to return the password used with a PasswordEncryptor implementation to decrypt encrypted passwords stored in Crypto properties files

UsernameToken handling in WSS4J 1.6

The CallbackHandler interface receives and requires the following information when handling UsernameTokens:

  • For both digest and plaintext cases, the CallbackHandler is given the username, password type and an identifier of WSPasswordCallback.USERNAME_TOKEN. It must set the password on the callback, and the validator does the comparison.

  • The custom password type case defaults to the same behaviour as the plaintext case, assuming wssConfig.getHandleCustomPasswordTypes() returns true.

  • For the case of a username token with no password element, the default behaviour is simply to ignore it, and to store it as a new result of type WSConstants.UT_NOPASSWORD.

Support for SAML2 assertions in WSS4J 1.6

Support for SAML2 assertions has finally arrived in WSS4J, via the forthcoming 1.6 release. This has been a long-standing feature request. WSS4J 1.5.x only supports SAML 1.1 assertions via the deprecated Opensaml1, and it supports them in a very limited manner, namely:

  • It only supports the creation of Authentication statements.

  • Processing essentially involves saving the assertions, it did not support validating enveloped signatures, or trust on the signatures, etc.

Several patches were submitted to WSS-146 to upgrade WSS4J to use Opensaml2. SAML2 support in WSS4J 1.6 consists of:

  • Support for creating signed/unsigned SAML 1.1/2.0 assertions, containing authentication, authorization, attribute statements etc.

  • This extensibility is achieved by letting the user implement a CallbackHandler instance.

  • The SAMLTokenProcessor can now process any type of assertion, verify an enveloped signature on it, and verify trust on the signature. It also verifies some holder-of-key requirements, e.g. that the Subject contains a KeyInfo element, and that the assertion is signed and trusted etc.

WSS4J 1.6 contains an extensive set of tests for both creating and processing different type of assertions. To illustrate the flexibility and simplicity of the CallbackHandler approach for constructing assertions, take a look at an abstract CallbackHandler here, as well as the concrete implementations (SAML 1.1 and SAML 2). As you can see, a fairly small amount of code can create a large variety of assertions.

Opensaml2 has a very large set of dependencies, but through some judicious pom exclusions, as well replacing the Opensaml DefaultBootstrap code to avoid loading velocity, the following dependencies are introduced in WSS4J via Opensaml (snippet from mvn dependency):

+- org.opensaml:opensaml:jar:2.4.1:compile
 |  \- org.opensaml:openws:jar:1.4.1:compile
 |     \- org.opensaml:xmltooling:jar:1.3.1:compile
 |        +- org.slf4j:slf4j-api:jar:1.6.1:compile
 |        \- joda-time:joda-time:jar:1.6.2:compile

The Opensaml2 port has a large impact on existing code for creating assertions, however it is thought that very few people used that code. It has a minimal impact on existing code for processing assertions, with several caveats:

  • WSS4J 1.5.x ignored (enveloped) signatures on SAML (1.1) assertions - this is no longer the case, so deployments which do not set the correct keystore/truststore config for dealing with signature verification will fail

  • The SAMLTokenProcessor no longer saves all tokens as an "WSConstants.ST_UNSIGNED" action. It saves tokens that do not have an enveloped signature as this action, and token which do have an enveloped signature are saved as a "WSConstants.ST_SIGNED" action.

  • The object that is saved as part of the action above has changed, from an Opensaml1 specific Assertion object, to an AssertionWrapper instance, which is a WSS4J specific object which encapsulates an Assertion, as well as some information corresponding to signature verification, etc.

JSR-105 support

WSS4J 1.6 has been ported to use the JSR 105 API for XML Digital Signature. Previously, WSS4J 1.5.x used the custom API of the Apache Santuario XML Security for Java library to create and process XML Digital Signatures.

WSS4J 1.6 has a minimum requirement of JDK 1.5 (note that WSS4J 1.5.x supports JDK 1.4). As JDK 1.5 does not contain an implementation of JSR 105, this means that XML Digital Signature is done via the JSR 105 implementation of Apache Santuario. However, when JDK 1.6+ is used, WSS4J 1.6 uses the JDK implementation of JSR 105 for signature creation and verification. You can override this by endorsing the Santuario jar.

The Apache Santuario XML Security jar is still required for the JDK 1.6 case, as there are compile-time dependencies in WSS4J for encryption/decryption, as well as for some algorithm parsing, and resource resolver stuff. One downside to the Santuario jar, is its dependence on Xalan for a small subset of operations. This dependency is removed for the 1.5 release of that library.

It is worth noting some changes to the main class used in WSS4J for signature creation as a result of the JSR-105 port. In WSS4J 1.5.x, after the signature certs and list of references to sign had been configured, the "computeSignature" method was called to compute the signature. The DOM element corresponding to the signature was independent of the pre-existing security header, and could be extracted later and inserted into the security header.

In WSS4J 1.6, you must tell "computeSignature" where to insert the signature element. A boolean "prepend" argument allows you to configure whether to prepend the generated Signature element to the security header, or whether to append it. If prepend is true, then an optional siblingElement argument can be used to prepend the signature element before this sibling element. Once computeSignature has been called, you have no control over where the signature element is inserted into the security header.

Basic Security Profile 1.1 compliance

The Basic Security Profile (BSP) 1.1 specification provides an industry-standard way of making sure that different WS-Security stacks can communicate with each other, by clarifying and narrowing the scope of the various WS-Security standards. WSS4J 1.5.x does not implement the BSP in any meaningful way. The WSSConfig class supports a "isWsiBSPCompliant" method (default is false), which will enable the generation of an InclusivePrefix list for signature generation, something that is mandated by the BSP spec.

WSS4J 1.6 provides support for the BSP 1.1 specification, in so far as it pertains to the core WS-Security specifications that WSS4J supports. The enforcing of BSP compliance for inbound messages is controlled by the WSSConfig class, as per WSS4J 1.5.x. An important change is that BSP compliance is now turned on by default. In addition, a new WSHandlerConstants configuration parameter has been added so that BSP compliance can be controlled via a WSHandler implementation.

Security Best Practices

This section describes a number of steps which should be taken to ensure that security best practices are followed and enforced.

Upgrade to WSS4J 2.3.x or 2.2.x

The 1.5.x and 1.6.x series of releases of WSS4J are deprecated. You should switch to either 2.3.x or the latest 2.2.x release as a matter of priority, as these branches contain up to date security fixes.

Upgrade to the latest minor release as soon as possible

You should always upgrade to the latest minor release in a timely manner, in order to pick up security fixes.

Use WS-SecurityPolicy to enforce security requirements

WSS4J can be used with a web services stack such as Apache CXF or Apache Axis in one of two ways: either by specifying security actions directly, or via WS-SecurityPolicy. WS-SecurityPolicy is a much richer way of specifying security constraints when processing messages, and gives you more automatic protection against various attacks then when configuring via security actions. See for example, this blog post on XML signature wrapping attacks. Therefore, you should always try to use WSS4J with a WS-SecurityPolicy requirement.

Use RSA-OAEP for the Key Transport Algorithm

WSS4J supports two key transport algorithms, RSA v1.5 and RSA-OAEP. A number of attacks exist on RSA v1.5. Therefore, you should always use RSA-OAEP as the key transport algorithm, and enforce this decision. For WS-SecurityPolicy, this means to avoid using any AlgorithmSuite that ends with "Rsa15" (e.g. "Basic128Rsa15").

For the "Action" based approach, there are different ways of enforcing that RSA v1.5 cannot be used for key transport depending on the version of WSS4J. From WSS4J 2.0.0, it is not allowed by default and no action is required. If you wish to allow it, then you must set the WSHandlerConstants.ALLOW_RSA15_KEY_TRANSPORT_ALGORITHM property to "true". For WSS4J 1.6.x, the RSA v1.5 key transport algorithm is allowed by default. In this case, you should explicitly configure WSHandlerConstants.ENC_KEY_TRANSPORT ("encryptionKeyTransportAlgorithm") to be "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p". This latter point requires the web services stack to set this property on the Request (it is known that Apache CXF does this).

Avoid using a cbc Symmetric Encryption Algorithm

There are some attacks that exploit the "cbc" mode of a Symmetric Encryption Algorithm. WSS4J has support for "gcm" mode algorithms as well. This can be specified via WSHandlerConstants.ENC_SYM_ALGO ("encryptionSymAlgorithm"), for example to "http://www.w3.org/2009/xmlenc11#aes128-gcm".

Use Subject DN regular expressions with chain trust

WSS4J 1.6.7 introduced the ability to specify regular expressions on the Subject DN of a certificate used for signature validation. It is important to add this constraint when you are supporting "chain trust", which is where you are establishing trust in a certificate based on the fact that the Issuer of the certificate is in your trust store. Otherwise, any certificate of this issuer will pass trust validation. See here for more information.

Specify signature algorithm on receiving side

When not using WS-SecurityPolicy (see point above about favouring the WS-SecurityPolicy approach), you should specify a signature algorithm to use on the receiving side. This can be done via WSHandlerConstants.SIG_ALGO ("signatureAlgorithm"). Setting this property to (e.g.) "http://www.w3.org/2000/09/xmldsig#rsa-sha1" will ensure that the signature algorithm allowed is RSA-SHA1 and not (e.g.) HMAC-SHA1. This latter point requires the web services stack to set this property on the Request (it is known that Apache CXF does this). See also the previous point about setting the key encryption transport algorithm.