Tuesday, March 18, 2014

Apache Santuario - XML Security for Java 2.0.0

In recent posts I have described some of the new features of the forthcoming Apache WSS4J 2.0.0 release. In particular, I focused on the changes and improvements to the existing "in-memory" (DOM-based) WS-Security implementation. However, the biggest new feature of WSS4J 2.0.0 will be a new streaming (StAX-based) WS-Security stack. In the next couple of posts, we will examine the core streaming XML Security functionality that will be available in the Apache Santuario - XML Security for Java 2.0.0 release.

The existing Apache Santuario - XML Security for Java implementation is DOM-based. What this essentially means is that the complete XML Document must be read into memory before being signed or verified. For large XML Documents this carries a corresponding performance penalty. In addition, it means that XML Signature is not feasible for very large documents. In contrast, the StAX API uses a streaming approach, resulting in very low memory usage.

The streaming XML/WS-Security functionality is split between the Apache Santuario and WSS4J projects. The Apache Santuario project contains the core streaming capabilities for XML Signature and Encryption. The Apache WSS4J project builds on this functionality to deliver a streaming WS-Security stack. The entire streaming security functionality is the work of Marc Giger, who donated his SWSSF project to Apache. Marc has done an outstanding job to implement this technically difficult task, and also to integrate the functionality into existing Apache projects. If you wish to experiment with the new functionality, it is available via the 2.0.0-rc1 release.

1) XML Signature test-cases

In this post we will focus on XML Signature only. I have uploaded some test-cases to github to show how to use the new StAX-based API. There are currently three junit tests in this project:
2) Outbound StAX configuration

To see how to configure the new outbound StAX-based XML Signature functionality, take a look at the "signUsingStAX" method used by the tests. The streaming XML Security functionality is configured by populating a XMLSecurityProperties Object. You must typically call the following methods:
  • properties.setAction(XMLSecurityConstants.Action) - an "Action" to perform, which for XML Signature purposes is XMLSecurityConstants.SIGNATURE. 
  • properties.setSignatureKey(Key) - The signing key. Can be a PrivateKey or SecretKey.
  • properties.setSigningCerts(X509Certificate[]) - The signing certs. May be inserted into the Signature KeyInfo depending on the Signature KeyIdentifier.
  • properties.addSignaturePart(SecurePart) - Add a SecurePart to sign, e.g. sign a given QName. You can also specify a digest method or transform algorithm here. You can also sign the entire request via SecurePart.setSecureEntireRequest(boolean).
  • properties.setSignatureAlgorithm(String) - Signature Algorithm to use. The default depends on the signing key.
  • properties.setSignatureDigestAlgorithm(String) - Signature Digest Algorithm to use. The default is the URI for SHA-1.
  • properties.setSignatureCanonicalizationAlgorithm(String) - The canonicalization algorithm to use. The default is XMLSecurityConstants.NS_C14N_EXCL_OMIT_COMMENTS.
  • properties.setSignatureKeyIdentifier(SecurityTokenConstants.KeyIdentifier) - How to reference the signing key/cert. The default is SecurityTokenConstants.KeyIdentifier_IssuerSerial.  
The valid Signature KeyIdentifier types are:
  • SecurityTokenConstants.KeyIdentifier_KeyValue
  • SecurityTokenConstants.KeyIdentifier_KeyName
  • SecurityTokenConstants.KeyIdentifier_IssuerSerial
  • SecurityTokenConstants.KeyIdentifier_SkiKeyIdentifier
  • SecurityTokenConstants.KeyIdentifier_X509KeyIdentifier
  • SecurityTokenConstants.KeyIdentifier_X509SubjectName
  • SecurityTokenConstants.KeyIdentifier_NoKeyInfo
By default, the Signature Element is attached as the first child of the root document.

3) Inbound StAX configuration

To see how to configure the new inbound StAX-based XML Signature functionality, take a look at the "verifyUsingStAX" method used by the tests. As with signature creation, it is necessary to create a XMLSecurityProperties Object, and to tell it what "Action" to perform. In addition you must call the following method, unless the complete signing key is contained in the Signature KeyInfo:
  • properties.setSignatureVerificationKey(Key) - a key to use to verify the Signature.
In addition, it is possible to pass a SecurityEventListener to record what security events were performed (see TestSecurityEventListener used in the tests). This allows the user to check what keys were used for signature verification, what algorithms were used, what was signed etc. See the verifyUsingStAX method as above for some simple code to check the signing key and the elements that were signed.

Wednesday, March 12, 2014

Apache CXF Authentication and Authorization test-cases

I've recently uploaded some test-cases to github that show different ways to authenticate and authorize a web services invocation using Apache CXF. Each project has the same two simple use-cases:
  • A JAX-WS request where the service requires a WS-Security UsernameToken over TLS.
  • A JAX-WS request where the service requires HTTP Basic Auth over TLS.
Each project has an "AuthenticationTest" that just illustrates some tests (including negative tests) for authentication, and then an "AuthorizationTest" that relies on authorizing the client based on roles that are retrieved as part of the authentication process somehow. The projects are as follows:
  • cxf-ldap: This project uses JAAS to authenticate a user via LDAP to a Apache Directory backend. The roles are also retrieved for the AuthorizationTest.
  • cxf-shiro: This project uses Apache Shiro for authentication and authorization.
  • cxf-spring-security: This project uses Spring Security for authentication and authorization.
  • cxf-syncope: This project uses the REST API of Apache Syncope for authenticating and authorizating users.
Feel free to download and play around with the projects.