ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

WS-Security in the Enterprise, Part 2: The Framework
Pages: 1, 2

WSSE Mapping

Now it is necessary to review the mapping of the Toolkit's elements to the major building blocks of the WSSE specification. A word of caution--according to Section 5 of the specification (PDF), "the <wsse:Security> header block provides a mechanism for attaching security-related information targeted at a specific recipient in the form of a SOAP actor/role." In other words, this header is extensible by design, and it is not feasible trying to address all of its possible applications. Therefore, the Toolkit's framework only attempts to map the tokens and relationships, existing within the main specification, while allowing for adding new types of tokens and processing later on.



WS-Security machinery is actually defined of a number of related documents, which are depicted in Figure 2.

Figure 2
Figure 2. WS-Security documents hierarchy

First, there is the main WSSE specification (PDF), which lays out the ground rules about the data passed in security headers, and the rules of inserting them into the SOAP messages. This specification defines the essential part, or XML "skeletons" of the contained security tokens, leaving it up to the so-called profile documents (referred to in the appropriate sections below) to fill the details about tokens' content, as well as referencing rules.

A full example of a signed WSSE Header with various types of tokens and a SAML assertion can be viewed here using the latest versions of IE or Mozilla-based browsers (it is also a part of the source download). Figure 3 presents an annotated outline of a WSSE Header with several tokens and a signature in it.

Figure 3
Figure 3. Annotated WSSE Header

Security Tokens

Section 6 of the WSSE specification describes various types of security tokens that may be added to a WS-Security Header. These security tokens are generally carried in WSSE Headers to pass certain security information to the request's target (or, in some cases, intermediate) service. The specification, however, does not dictate what kind of information is passed around, leaving it up to the communicating applications to agree on semantics. What is enforced, however, are the insertion and processing rules for the supported types of tokens.

WSSE security tokens are represented by the classes in the wsse.Toolkit.Tokens.Wss package. Most of the supported token types are creatable from the existing XML; i.e., they can be extracted from one message and used in another one, which was one of the requirements for the Toolkit. All of the tokens, described below (with the exception of the header token itself), are optional. Their presence in the security header is dictated not by the WSSE specification, but by the application's logic.

Token validation against the standards takes place when XML is generated for a particular token, or when a token is created from the existing XML element. XML generation and its validation are delayed until the token is explicitly asked for its XML content. This allows for avoiding excessive XML parsing and for implementing only a single validation point, rather than scattering it over a number of places where XML elements may be constructed and updated. XML generation and insertion depends on the tokens' ordering, and, in certain cases, this ordering is important for proper processing of the generated header.

The Toolkit includes two different types of tokens--simple ones, which represent a single XML element, and composite tokens (represented by the WsCompositeToken class), which may optionally include other tokens. Rules for processing and handling the composite tokens are different from those of simple ones, since the composite tokens must propagate any operation (such as setting the owner document) down to the children, and to define a number of additional search/replace methods on the contained tokens.


<SOAP-ENV:Header>
  <wsse:Security SOAP-ENV:actor="myService" 
                 SOAP-ENV:mustUnderstand="1">
    ...
  </wsse:Security>
</SOAP-ENV:Header>

A WSSE Header itself, shown in the preceding code example, is represented by the WsseHeaderToken class. This class handles processing of all of the contained security tokens, enforces the header's conformance to the specification, and generates the header's XML. It supports the SOAP 1.1 actor attribute, as specified in the Section 5 of the WSSE specification. The SOAP mustUnderstand attribute can be set on the generated header, but enforcement of its processing rules should happen prior to constructing new headers and, therefore, falls outside of the Toolkit's scope.

Additionally, the WsseHeaderToken class includes a number of helper functions to perform common header operations, such as inserting a timestamp or signing and encrypting its tokens. It also exposes generic methods to insert additional types of token processors for extensibility, as demonstrated in Example 2. All added processors are called in turn, according to their insertion order--this helps to ensure that newly generated XML elements are made available for the processors later in the chain.


<wsse:Security ...>
  <wsse:UsernameToken wsu:Id="xdJKdk6hgg68h">
    <wsse:Username>Admin</wsse:Username>
    <wsse:Password Type="wsse:PasswordDigest">
      xcYjkd9Hjkksds...
    </wsse:Password>
    <wsse:Nonce>WKjd73j0...</wsse:Nonce>
  </wsse:UsernameToken>
</wsse:Security>

The wsse.Toolkit.Tokens.Wss.UsernameToken class handles the UsernameToken element, described in the Section 6.2 of the WSSE specification and in the Section 3 of Username token profile (PDF). The UsernameToken element is used as a standard means of passing the user's name and (optionally, as a confirmation mechanism) his or her password to the destination service. It also supports addressing by wsu:Id, which is used to reference it from the processing nodes, such as XML Signature. Auxiliary classes from the package wsse.Toolkit.Directory are used to retrieve user information from the specified User Store--it is represented in the code via wsse.Toolkit.Directory.IUserDirectory interface.


<wsse:Security ...>
  <wsse:BinarySecurityToken ValueType="wsse:X509v3"
                            EncodingType="wsse:Base64Binary"
                            wsu:Id="MyX509">
    MIIOlskew78Hjkds...
  </wsse:BinarySecurityToken>
</wsse:Security>

Binary tokens, from Section 6.3 of the WSSE specification and Section 3 of the X.509 token profile (PDF), which are used in WSSE to pass key or certificate data, are supported by the Toolkit's wsse.Toolkit.Tokens.Wss.BSTToken class. Since XML is a text-based format, the value of this element has to be Base64-encoded prior to inserting it into the security header. Although several profile specifications already exist (or are being developed), representing different types of binary tokens (Kerberos tickets, for instance), the Toolkit will only support X.509 tokens, as they are significantly more widespread.

Due to the extreme flexibility and great variety of possible XML security tokens, details of attaching them to the WSSE Header (see Section 6.4 of the specification) are completely deferred to the specific profile documents--for other supported token types, the main WSSE specification at least defines a general insertion framework. The Toolkit provides the class wsse.Toolkit.Tokens.Wss.SamlAssertionToken to implement the SAML token profile (PDF), which details the attachment of SAML Assertions to WSSE Headers. Assertion generation is delegated to configured providers, which are accessed via the wsse.Toolkit.Saml.IAssertionGenerator interface.

Token References

In general, providing a good reference framework for WSSE security tokens is a very non-trivial task, especially remembering that most elements may occur more than once in a particular header. Fortunately, the Toolkit does not need to provide a full generic implementation--when tokens are parsed from an existing header, it is reasonable to assume that the application has certain knowledge of the security tokens that it is intending to pass on.

References' implementations rely on certain specific characteristics of various types of tokens to retrieve or construct their instances. Usage of some tokens may be restricted (either by the standards, or by application policy) to only a single token per header (like timestamps, for instance, or by rejecting requests with more than one Username XML element); others may specify additional search context (such as the signer's public key name), sufficient for unambiguously retrieving the desired token from the processed WSSE header.


<wsse:SecurityTokenReference wsu:Id="X509STR">
  <wsse:Reference URI="#MyX509"/>
</wsse:SecurityTokenReference>

The WSSE specification defines a wsse:SecurityTokenReference element as a common way of referencing security tokens, be they X.509 certificates or SAML assertions. In the Toolkit, references to security tokens are handled via derivatives from the wsse.Toolkit.Tokens.Refs.WsTokenRef class. Generally, reference elements are going to be added to other security tokens (for instance, DSig) during their processing, so there is no need to explicitly insert instances of reference classes into WsCompositeToken objects. The only exception to this rule is the wsse.Toolkit.Tokens.Refs.Xml.SecureTokenRef class, which represents the wsse:SecurityTokenReference XML element in the Toolkit's framework.

Since the wsse:SecurityTokenReference element is supposed to handle references to almost any imaginable type of security token, its structure is by necessity very complicated. Section 7.1 of the WSSE specification lists several possible types of reference mechanisms that could be used with this token:

  • Direct References: Shown in the above example; this is probably the most intuitive and unambiguous type of referencing elements, preferably--by utilizing uniqueness (within a particular WSSE Header) of their wsu:Id attribute. Note that it may also reference external URLs.
  • Key Identifiers: Allow referencing a security token by some unique token trait, and, therefore, is profile-specific for each token. In the case of X.509 tokens, it is the certificate's X.509 SubjectKeyIdentifier value, as specified in Section 3.2.1 of the X.509 Token Profile.

Several additional reference mechanisms are defined for the STR tokens, including Key Names and Embedded References in the main WSSE specification. However, due to lack of space, they are not going to be covered here in any detail.

Token Processing

Besides simply carrying security tokens, the WSSE specification utilizes XML Signature and XML Encryption recommendations to protect the integrity and confidentiality of SOAP messages. In the Toolkit, this functionality is represented by Token Processors. Their main common feature is that they all work on already-present nodes in the security headers, possibly altering or removing them, and inserting new ones into the WSSE header to reflect the processing results. This behavior is defined by the wsse.Toolkit.Processors.ITokenProcessor interface, and concrete implementations will provide processor-specific logic. At the moment, implementation of two processors for XML Signing and Encryption is planned and will be covered in future installments.

Conclusion

This article provided a high-level overview of major components of the WSSE Toolkit (tokens, references, and processors) and how they match various parts of the WS-Security standards. In the next installment we will have fun dissecting the verification requirements of a WSSE Header and describing implementation details of Username, Binary, and SAML tokens, as specified in the development plan for the Toolkit in the opening article of this series.

Resources

The project's source that accompanies this article is being developed in Java using Borland's JBuilder IDE, and includes its project files. There is also a crude Windows batch file to build the class hierarchy included with the archive, which may be downloaded here. As the project moves forward, the implementation files will be updated or added to the project, and made available with the new installments of this series. Please, direct all comments regarding the project's source code to my email address (see the author's link at the beginning), as I prefer to separate programming and standards discussions.

Denis Piliptchouk is a senior technical member of BEA's AquaLogic Enterprise Security group, participates in OASIS WSS and WS-I BSP standards committees, and regularly contributes to industry publications.


Return to ONJava.com.