All major web services stacks provide some level of support for WS-Security and related web services security standards. The three open source stacks I've covered in this series — Apache Axis2, Sun/Oracle Metro, and Apache CXF — all provide a fairly high level of support for these standards. But their support differs significantly in many ways, including both the security operation and how the stacks are configured with run-time security parameters.
One important area of difference relates to the completeness and correctness of the security implementations. WS-Security and WS-SecurityPolicy allow many variations of security configurations, including different types of keys and certificates, algorithm suites, security tokens, and signing/encrypting specifications. WS-Trust and WS-SecureConversation expand the number of options even further. With so many possible configurations, no web services stack can possibly test them all. Even testing each possible option value in isolation is difficult, and most stacks don't try.
In this article, you'll first learn more about the issues of security interoperability among web services stacks. Then you see how the Axis2, Metro, and CXF compare on several measures of correctness and usability, based on my research for the last dozen or so articles of this series.
Security standards provide far too many combinations of options for comprehensive testing. Many of the standards supply little in the way of examples, and nothing in terms of test suites, so conformance to the "standard" is often a matter of opinion and conjecture. As a result, stacks that claim to support a particular standard rarely do any extensive verification of their support.
Instead of trying to test against the standard, each stack uses a limited number of security configurations for its own testing, along with an even more limited number of configurations in interoperability tests with other stacks. Other than that, the developers for each stack respond to bug reports from users encountering security configuration or interoperability issues. This limited testing for a complex set of standards means you'll often encounter problems if you try anything that's not in the mainstream. Even in the relatively small number of security configurations tested for the security discussions and performance comparisons in the articles of this series, I found several problems of this type.
Some efforts to improve the quality of web services security code have been made, including the work of an industry-wide organization and vendor-driven interoperability testing. The latter, in particular, has helped establish a basic level of compatibility among stacks, but the benefits have been limited because of the small number of configurations tested.
WS-I Basic Security Profile
From the start, SOAP web service specifications have offered many choices for implementers and users. Partly this was by design. Other cases are due to oversights in the standards: Expected behaviors were not specified in enough detail, so implementers had to guess what needed to be done. The problem with too many choices is that implementers lack the resources to test all the possible combinations fully, so the web services stacks support some sets of choices well, others poorly, and still others not at all. This situation creates major problems for interoperability, because there's no guarantee that different stacks support the same choices.
Choice overload was such a problem in the early years of SOAP that an industry-wide group was created for the specific purpose of limiting the number of possible configurations by defining "best practices" approaches. This group, the Web Services Interoperability Organization (WS-I), produced a number of profiles requiring particular choices to be used or avoided (see Resources). Through these profiles, WS-I has had a major influence in shaping the current third generation of web services stacks.
Security is one of the areas WS-I has covered in profiles. The WS-I Basic Security Profile Version 1.1 (referred to as BSP 1.1) is the current main document in the security area. This document includes a wide range of requirements, but in keeping with the focus of WS-I, most of these requirements deal with web services stack implementations rather than end-user security configurations. BSP 1.1 does not deal with WS-Security configuration in WS-SecurityPolicy at all, but a few of its requirements can be translated into WS-SecurityPolicy terms.
When you use digital signatures, BSP 1.1 requires you to follow the W3C Exclusive Canonicalization Recommendation, an XML canonicalization algorithm that ignores comments and unnecessary context information (see Resources). This algorithm is the default assumed by WS-SecurityPolicy in the absence of any choice, so all you need to do to meet this requirement is not specify a different canonicalization algorithm (such as
BSP 1.1 also adds some other requirements for both signatures and encryption that constrain the algorithm-suite values defined in WS-SecurityProfile, but these basically just restrict the choices to those using TripleDes, Aes128, or Aes256 encryption, and SHA1 digesting (excluding only the Aes192 encryption and SHA256 digest options offered by WS-SecurityPolicy). Other BSP recommendations restrict how various security tokens are to be referenced and used.
The WS-I BSP has undoubtedly contributed to interoperability across web service security implementations, but aside from these minor points, it hasn't done anything toward reducing the complexity of security-configuration choices. An updated version of the BSP that was more-specifically oriented toward WS-SecurityPolicy configurations would be very useful to help establish best practices for security architects using modern policy-based configurations, but unfortunately the WS-I has not shown interest in such an update.
Vendor-driven interoperability testing across stacks has been a more significant factor in improving the quality of web service security implementations. Microsoft® has been a driving force in this area, hosting a series of "interoperability plug-fests" at its campus where developers of other web services stacks (both commercial and open source) are invited to participate in testing various scenarios between their code and the Microsoft implementation (see Resources). Security has been a major focus of the plug-fests.
This interoperability testing has helped establish a basic level of compatibility among stacks, but the benefits have been limited because of the small number of configurations tested. The focus on interoperability with the Microsoft implementation (rather than a test suite based on the actual standards) has also been a limitation, though in practical terms this is much easier to handle than full cross-compatibility tests among a dozen or more stacks.
Security issues and limitations
In this column series, I've tested a variety of security configurations on three web services stacks, finding several issues with each stack. Limited interoperability testing (using one stack for the client and another for the server, only tried for the WS-SecureConversation tests) demonstrated even more issues. In the case of one stack, Apache Axis2, I also found significant performance problems. All these issues have been reported to the developers for each stack, and some have been fixed in the latest releases. In this section, I'll summarize the current state of the three stacks with respect to the testing I did for these articles.
The problems I found with Axis2 include WS-SecureConversation policy handling, wherein the bootstrap policy definition appears to be completely ignored in operation. Because this means Axis2 uses a canned configuration for its WS-SecureConversation support, it's only compatible with other stacks using that same configuration.
In terms of the security runtime, Axis2 has a major issue with client-side handling of symmetric bindings (as discussed in "WS-Security without client certificates"). The client runs progressively slower as more requests are made. I consider this a hard bug, rather than a performance issue, because of the progressive nature of the problem.
Axis2 security handling is also plagued by consistently slow operation any time security is used (see "CXF performance comparison" for some results). This performance issue appears to be rooted in incompatibilities between the AXIOM object model used by Axis2 and the standard DOM used by the security code, so the problems are likely to continue until and unless AXIOM is enhanced to provide full DOM compatibility.
Finally, in my opinion, Axis2 tends to suffer from a disconnect between the core web services engine (the actual Axis2 code) and the security code (the Rampart and Rahas security modules). Early on we (the Axis2 committers) decided to separate the security code from the core code, allowing these components to be separately enhanced and released. Unfortunately, this has resulted in the security code being treated as an optional component, and Axis2 releases have been made that do not work with the then-current Rampart release. The recent Axis2 1.5.2 release is an example: the binary distribution is missing a JAR file required for security handling, so there's no easy way to make it work with Rampart. This was corrected in the current Axis2 1.5.3 release, but the very fact that an official release would ship without working security support demonstrates the disconnect.
None of the significant Axis2 problems I found in writing these articles has been corrected as of the latest Axis2 and Rampart releases.
Tests for the articles in this series also revealed some significant problems with
Metro. The biggest problem is Metro's handling of signing message bodies. If the policy includes a
<sp:OnlySignEntireHeadersAndBody/> assertion, everything is fine, but if this assertion isn't used, Metro incorrectly signs the content of the body, rather than the body element itself. Stacks that handle the signing correctly will reject messages signed in this way by Metro.
Metro also broke with the WS-SecureConversation policy used in "WS-Trust and WS-SecureConversation." The problem in this case was that the policy used different algorithm suites for the bootstrap message exchange with the Security Token Service (STS) and the actual conversation with the service. Metro ignored this and just used a single algorithm suite for both. This is not as significant a problem as the signing issue, in that there's little reason to use two different algorithm suites in practice, but it's still an error.
Finally, Metro also had problems relating to the use of one-way encryption or signing reported in "Understanding WS-Policy." None of these problems has been corrected as of the latest Metro release.
Just as with the other stacks, I found some CXF problems in testing for these articles. In almost every case, the problems were corrected in a new CXF release before the article was published. The only exception was for the problems relating to the use of one-way encryption or signing reported in "Understanding WS-Policy," — which have now been corrected in the CXF 2.3.1 release.
Comparing the stacks
Any attempt to rank web services stacks on their security support will necessarily be highly subjective, because each stack has both strengths and weaknesses. In trying to give a balanced assessment, I've broken the ranking down into four factors and assigned a numeric rating in the classic 1-to-10 (worst-to-best) range for each stack:
- Correctness: How many implementation errors are known, and how serious are the errors?
- Completeness: How complete is the security implementation?
- Performance: How much overhead does the security handling add?
- Usability: How easy is it to configure the security code?
Axis2 has some significant problems, and the disconnect between the core code and the Rampart security module is an issue of concern, but overall it seems fairly solid. Score: Axis2 — 6.
Metro has some major issues, in particular the incorrect handling of signatures when
<sp:OnlySignEntireHeadersAndBody/>. Like Axis2, though, it generally seems fairly solid, and the integration of the security code into the main release makes complete failures less likely than with Axis2. Score: Metro — 7.
CXF has only relatively minor known issues, and the fast responses to problems and quick release cycle mean problems generally are corrected soon after they're found. Score: CXF — 8.
To be fair on this point, I've only considered problems experienced directly in the course of these articles. Checking the bug-tracking systems for the stacks will show other, potentially more significant, problems. You need to use care when looking at these — some of the problems reported may be caused by user errors — but it's a worthwhile exercise if you're considering standardizing on a particular stack. See Resources for information on the bug-tracking systems for the three stacks.
All three stacks provide support for all the major security standards. However, Axis2 support is limited in at least two respects. For WS-Policy, Axis2 code generation only works with the outdated submission version from 2004, rather than the standard W3C version released in 2007. For WS-SecureConversation, Axis2 implements a "canned" configuration, ignoring any policy configuration you supply. Scores: Axis2 — 6; Metro — 7; CXF — 7.
Axis2 is clearly the loser when it comes to any security-performance rankings. In every form of message-level security handling it creates much more processing overhead than either Metro or CXF. Metro is slightly faster than CXF overall, so for this factor my scores are: Axis2 — 4; Metro — 8; CXF — 7.
Axis2's security configuration is somewhat painful. On the client side, it requires you either to embed run-time parameters into the service WSDL or to configure the parameters directly in your client code. Either way, you must actually activate the security handling in your client code. On the server side, you have to modify the generated services.xml file to include run-time parameters and to activate the security handling. Axis2 also tends to silently ignore anything it doesn't understand in the policy configuration. Score: Axis2 — 5.
Metro is probably a little easier than Axis2 to work with, but it always requires you to add your run-time parameters into the service WSDL (or at least reference a separate document defining the parameters, on the client side). I believe this is inappropriate, because the WSDL is supposed to represent the published service contract. Metro also provides little documentation on configuring and using security features outside of the NetBeans/Glassfish bundle. Finally, in my experience, the error messages you get when there's a configuration problem tend to be obscure, making it difficult to track down the cause. Score: Metro — 6.
CXF has the cleanest approach to configuration, normally using separate files for the run-time security parameters on both client and server. You also have the option of configuring everything directly using Spring, or in your code. Beyond the basic configuration issues, CXF also supports external policy references in WSDL, an important feature for organizations that want to standardize security policies across the enterprise. Finally, CXF seems to have the best handling for unsupported policy components, generating warning messages to let you know that the policy is not fully supported. Score: CXF — 8.
Table 1 summarizes my rankings:
Table 1. Web service stack rankings
|Apache Axis2||Sun/Oracle Metro||Apache CXF|
These rankings are not intended to be definitive, so if you are using them in making a decision about your own use of a stack, be sure to review my justifications and make your own judgment. Also, the rankings apply only to the base open source projects; commercial stacks based on the open source versions may use their own security code and other extensions (as is the case with IBM's WebSphere web services support, which is based on the Axis2 runtime but uses entirely different security code). You'll need to look at the differences between the commercial code and the open source base to see which parts of the rankings may apply.
All three of the open source web services stacks looked at in this series to date provide good support for security features. Each stack has some strengths and weaknesses in the security area, and in this article, you've seen a summary of how they compare based on my experiences in working with the three over the course of the last dozen or so articles.
The next article in the series takes a different tack, looking into the structure of WSDL service definitions and developing a tool to verify WSDLs and convert them into the recommended best-practices form.
- Axis2: Axis 2 is an open source web services stack from the Apache Software Foundation.
- CXF: CXF is another open source web services stack from Apache.
- Metro: Metro is an open source web services stack that incorporates the latest reference implementations of the JAXB 2.x and JAX-WS 2.x Java standards.
- Web Services Interoperability Organization: WS-I has helped set best practices for both basic web services and security features.
- Exclusive XML Canonicalization: For digital signatures, BSP 1.1 requires the canonicalization algorithm specified in this W3C Recommendation.
- Web Services Interoperability Plug-Fest: The Plug-Fests organized by Microsoft have helped promote interoperability among web services stacks.
- Axis2 Jira tracks the bug reports for the core Axis2 code, while Rampart Jira tracks the bugs relating specifically to security handling.
- CXF Jira tracks all CXF bugs, with the security handling ones included under the general WS-* Components category.
- Metro Issue Tracker tracks all Metro bugs, with the security and other WS-* issues under the WSIT component.
- Browse the technology bookstore for books on these and other technical topics.
- developerWorks Java technology zone: Find hundreds of articles about every aspect of Java programming.
- Get involved in the My developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.