Red Hat Training

A Red Hat training course is available for Red Hat Fuse

9.2. STS Demonstration

9.2.1. Overview of the Demonstration

Overview

The standalone Apache CXF distribution includes an STS demonstration in the following location:
CXFInstallDir/samples/sts
This demonstration illustrates a complete Holder-of-Key scenario, including all of the code for the client, server, and standalone STS.

The demonstration scenario

Figure 9.5, “STS Demonstration Scenario” shows an overview of the STS demonstration scenario and the steps required to implement single-sign on in the context of WS-Trust and the STS.

Figure 9.5. STS Demonstration Scenario

In this Holder-of-Key scenario, there are two main stages involved in invoking an operation on the server: first the client obtains a single-sign on token (SAML token) from the STS; then the client invokes the WSDL operation on the server, embedding the SAML token in the SOAP security header.

The client-STS connection

The client-STS connection is used to obtain the single-sign on token (SAML token) from the STS. This connection is secured by a symmetric binding (for message protection) and messages must include a UsernameToken (for client authentication).
The symmetric binding is characterized by the fact that only one key pair is required (the STS X.509 certificate and private key) and the symmetric session key is derived from this key pair. To support the symmetric binding, the client must be configured with the STS X.509 certificate (public key) and the STS must be configured with the corresponding STS private key.
The UsernameToken credentials, which must accompany the Issue request sent to the STS, are used to authenticate the client.

The client-server connection

The client-server connection is established after the client has obtained the single-sign on token from the STS and is used to invoke the greetMe WSDL operation. This connection is secured by an asymmetric binding (for message protection and authentication).
The asymmetric binding is characterized by the fact that two key pairs are required: the Initiator token (a SAML token containing the client X.509 certificate); and the Recipient token (server X.509 certificate and private key). Both the client key pair and the server key pair are used for message protection.
The SAML token sent by the client contains a copy of the client's X.509 certificate and is used to authenticate the client (in a Holder-of-Key scenario).

Invocation steps

In the STS demonstration scenario shown in Figure 9.5, “STS Demonstration Scenario”, the client makes a secure invocation on the server as follows:
  1. The secure invocation is initiated when the client calls the greetMe() method.
  2. Before sending a request message to the server, the client must ask the STS to issue the token that will be used for single sign-on. The client delegates this task to the STSClient bean, which is itself a fully-fledged WS client that can communicate with the STS.
    To establish the connection to the STS, the STSClient bean must initialize a symmetric binding, as follows:
    1. The STSClient generates an ephemeral key (the symmetric session key).
    2. The STSClient encrypts the ephemeral key using the STS public key (X.509 certificate).
    3. The ephemeral key is then used for signing and encrypting the SOAP message parts sent between the STSClient bean and the STS.
  3. The STSClient bean now constructs the RequestSecurityToken (RST) message, which it sends to the STS. The STSClient embeds the client's X.509 certificate (to be used as the client's identity in the Holder-of-Key scenario) and the client's UsernameToken credentials (UT) into the RST message.
    The STSClient bean now uses the RST message to invoke the STS Issue operation.
  4. When the RST message arrives in the STS, the STS endpoint immediately tries to authenticate the embedded UsernameToken credentials. If the UsernameToken credentials could not be authenticated, the message would be rejected.
  5. The STS now processes the issue token request. The RST asks the STS to generate a SAML token, using the client's X.509 certificate as the Holder-of-Key identity. The STS constructs a RequestSecurityTokenResponse (RSTR) message containing a SAML token, taking care to sign the generated SAML token using the STS signing key.
  6. The STS returns the RSTR message containing the signed SAML token.
  7. The client is now ready to send the greetMe request to the server. The signed SAML token that was issued by the STS is embedded in the SOAP security header of the request message.
  8. The first thing that the server does is to check that the SAML token is signed by the STS public key. To be more precise, what the server actually does is to check whether the SAML token is signed by any trusted key—that is, any of the public keys that can be found in the servicestore.jks keystore file.
    If the SAML token is not signed by a trusted key, the message is rejected, because it is then impossible to establish trust in the SAML token.
  9. The server now performs the Holder-of-Key check, to establish the client's identity (effectively, authenticating the client).
    The X.509 certificate embedded in the SAML token is meant to be the client identity, but the client must also prove that it possesses the corresponding private key for the certificate, in order to be authentic. It turns out that, as part of the natural configuration of the asymmetric binding policy, the client is configured to sign various parts of the SOAP message using the myclientkey private key. The server therefore checks all of the message's signing keys and if it finds one that matches the X.509 certificate in the SAML token, it knows that the client is in possession of the private key.
  10. If all of the security checks have been successful, the server now invokes the implementation of the greetMe WSDL operation.

Single-sign on and scalability

Notice that the client in this scenario is required to hold a copy of the server's X.509 certificate (myservicekey certificate). The server's certificate must be distributed to the clients using some out-of-band approach, which creates some extra work when scaling up to a large system.
On the other hand, the server requires absolutely no knowledge whatsoever about the client. It relies entirely on the STS to establish trust with a client. This is a great advantage for scalability of the system.

9.2.2. STS WSDL Contract

Overview

The STS WSDL contract specifies the address used to contact the STS and the STS WSDL also specifies the kind of security that applies to incoming connections. In the current demonstration, the STS requires clients to support the symmetric binding and to authenticate by providing UsernameToken credentials.

Location of the STS WSDL contract

The STS WSDL contract can be found in the following location:
CXFInstallDir/samples/sts/wsdl/ws-trust-1.4-service.wsdl

Parts of the contract

The most important parts of the STS WSDL contract are, as follows:
  • STS port type—the standard WSDL port type for the STS, as defined the WS-Trust specification.
    Note
    There are some other standard WSDL port types defined in the WSDL file, but these port types are not used in this demonstration.
  • WSDL binding—the SOAP binding for the STS port type. Policies are enabled by applying them to various parts of the WSDL binding.
  • WSDL service and port—the WSDL port element specifies the address of the STS Web service endpoint.
  • Binding policy—a WS-Policy element that specifies how connections to the STS must be secured.
  • Signed/encrypted parts policies—a WS-Policy element for input messages and a WS-Policy element for output messages, specifying which parts of the incoming SOAP messages and the outgoing SOAP messages must be signed and encrypted.

STS port type

The STS port type provides an abstract description of all the WSDL operations supported by the STS. The STS port type appearing the STS WSDL file is taken directly from the WS-Trust specification. Only the Issue operation is actually implemented in this demonstration, however.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
        targetNamespace="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
        xmlns:tns="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
        xmlns:wstrust="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:wsap10="http://www.w3.org/2006/05/addressing/wsdl"
        xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
        xmlns:wsp="http://www.w3.org/ns/ws-policy"
    xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
    >
  ...
  <!-- This portType is an example of an STS supporting full protocol -->
  <wsdl:portType name="STS">
    <wsdl:operation name="Cancel"> ... </wsdl:operation>
    <wsdl:operation name="Issue"> ... </wsdl:operation>
    <wsdl:operation name="Renew"> ... </wsdl:operation>
    <wsdl:operation name="Validate"> ... </wsdl:operation>
    <wsdl:operation name="KeyExchangeToken"> ... </wsdl:operation>
    <wsdl:operation name="RequestCollection"> ... </wsdl:operation>
  </wsdl:portType>
  ...
</wsdl:definitions>

WSDL binding

The WSDL binding for the STS is a regular SOAP binding (as could be generated using the Apache CXF wsdl2soap utility), except for the wsp:PolicyReference elements, which are used to apply the relevant security policies to the binding. Hence, the policy identified by UT_policy is applied to the whole binding and the Input_policy and the Output_policy are applied respectively to the input messages and the output messages of each operation.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
  ...
  <wsdl:binding name="UT_Binding" type="wstrust:STS">
      <wsp:PolicyReference URI="#UT_policy" />
      <soap:binding style="document"
          transport="http://schemas.xmlsoap.org/soap/http" />
      <wsdl:operation name="Issue">
          <soap:operation
              soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue" />
          <wsdl:input>
              <wsp:PolicyReference URI="#Input_policy" />
              <soap:body use="literal" />
          </wsdl:input>
          <wsdl:output>
              <wsp:PolicyReference URI="#Output_policy" />
              <soap:body use="literal" />
          </wsdl:output>
      </wsdl:operation>
      <wsdl:operation name="Validate"> ... </wsdl:operation>
      <wsdl:operation name="Cancel"> ... </wsdl:operation>
      <wsdl:operation name="Renew"> ... </wsdl:operation>
      <wsdl:operation name="KeyExchangeToken"> ... </wsdl:operation>
      <wsdl:operation name="RequestCollection"> ... </wsdl:operation>
  </wsdl:binding>
  ...
</wsdl:definitions>
For full details of how policy references work, see Policies and policy references.

WSDL service and port

The WSDL service and WSDL port elements are used to define the address of the STS endpoint (specified by the location attribute of soap:address).
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
  ...
  <wsdl:service name="SecurityTokenService">
      <wsdl:port name="UT_Port" binding="tns:UT_Binding">
         <soap:address location="http://localhost:8080/SecurityTokenService/UT" />
      </wsdl:port>
  </wsdl:service>
  ...
</wsdl:definitions>

Binding policy

The binding policy, UT_policy, defines what kind of security is applied to incoming STS connections.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
  ...
  <wsp:Policy wsu:Id="UT_policy">
      <wsp:ExactlyOne>
         <wsp:All>
            <wsap10:UsingAddressing/>
            <sp:SymmetricBinding
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <wsp:Policy>
                  <sp:ProtectionToken>
                     <wsp:Policy>
                        <sp:X509Token
                           sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                           <wsp:Policy>
                              <sp:RequireDerivedKeys />
                              <sp:RequireThumbprintReference />
                              <sp:WssX509V3Token10 />
                           </wsp:Policy>
                        </sp:X509Token>
                     </wsp:Policy>
                  </sp:ProtectionToken>
                  <sp:AlgorithmSuite>
                     <wsp:Policy>
                        <sp:Basic128 />
                     </wsp:Policy>
                  </sp:AlgorithmSuite>
                  <sp:Layout>
                     <wsp:Policy>
                        <sp:Lax />
                     </wsp:Policy>
                  </sp:Layout>
                  <sp:IncludeTimestamp />
                  <sp:EncryptSignature />
                  <sp:OnlySignEntireHeadersAndBody />
               </wsp:Policy>
            </sp:SymmetricBinding>
            <sp:SignedSupportingTokens
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <wsp:Policy>
                  <sp:UsernameToken
                     sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                     <wsp:Policy>
                        <sp:WssUsernameToken10 />
                     </wsp:Policy>
                  </sp:UsernameToken>
               </wsp:Policy>
            </sp:SignedSupportingTokens>
            <sp:Wss11
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <wsp:Policy>
                  <sp:MustSupportRefKeyIdentifier />
                  <sp:MustSupportRefIssuerSerial />
                  <sp:MustSupportRefThumbprint />
                  <sp:MustSupportRefEncryptedKey />
               </wsp:Policy>
            </sp:Wss11>
            <sp:Trust13
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <wsp:Policy>
                  <sp:MustSupportIssuedTokens />
                  <sp:RequireClientEntropy />
                  <sp:RequireServerEntropy />
               </wsp:Policy>
            </sp:Trust13>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
  ...
</wsdl:definitions>
The binding policy defines the STS security policy to be a symmetric binding. This implies that security is applied at the SOAP message level, where parts of the SOAP payload are liable to be encrypted and/or signed. Because this is a symmetric binding, the keys used for encrypting and signing in both directions are derived from a single key, specified by the sp:ProtectionToken element (which is ultimately configured to be the mystskey private key and X.509 certificate on the STS server). The client is required to include a WSS UsernameToken in the SOAP security header, which is used by the STS to authenticate the client.
For a more detailed discussion of the symmetric binding policy, see .

Signed parts and encrypted parts policies

The Input_policy policy is used to specify exactly which parts of an input message should be encrypted and/or signed by the symmetric session keys. In addition to signing and encrypting the SOAP body, the standard WS-Addressing SOAP headers are also signed (which protects them from tampering by third-parties).
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
  ...
   <wsp:Policy wsu:Id="Input_policy">
      <wsp:ExactlyOne>
         <wsp:All>
            <sp:SignedParts
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <sp:Body />
               <sp:Header Name="To"
                  Namespace="http://www.w3.org/2005/08/addressing" />
               ...
            </sp:SignedParts>
            <sp:EncryptedParts
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <sp:Body />
            </sp:EncryptedParts>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
  ...
</wsdl:definitions>
The Output_policy policy is used to specify exactly which parts of an output message should be encrypted and/or signed by the symmetric session keys.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
  ...
   <wsp:Policy wsu:Id="Output_policy">
      <wsp:ExactlyOne>
         <wsp:All>
            <sp:SignedParts
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <sp:Body />
               <sp:Header ... />
               ...
            </sp:SignedParts>
            <sp:EncryptedParts
               xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
               <sp:Body />
            </sp:EncryptedParts>
         </wsp:All>
      </wsp:ExactlyOne>
   </wsp:Policy>
  ...
</wsdl:definitions>

9.2.3. Security Token Service Configuration

Overview

Figure 9.6, “Demonstration STS Configuration” shows an overview of how the STS is configured for the current demonstration.

Figure 9.6. Demonstration STS Configuration

Aspects of configuration

The current demonstration configures the following aspects of the STS:
  • WSDL contract and security policies—as already discussed in Section 9.2.2, “STS WSDL Contract”, the policies in the WSDL contract are used to define the type of security that protects incoming connections to the STS. In particular, it is important that some form of client authentication is required by these security policies.
  • STS plug-in configuration—as described in Section 9.1.1, “Overview of the STS”, the STS has a plug-in architecture. In order to instantiate an STS server, you must assemble and configure the STS plug-ins that you want to use.
  • STS signing key—you must configure the STS with its own signing key, which effectively provides the stamp of authenticity for any tokens issued by the STS.
  • List of known Web service endpoints—you can optionally install a service plug-in into the STS, which is used to define a list of known Web service endpoints that can use the STS (see Section 9.4, “Enabling AppliesTo in the STS”).
  • JAX-WS endpoint configuration—you must define a Web service endpoint for the STS, which clients use to connect to the STS. In the JAX-WS endpoint you specify the X.509 certificate and private key that are used as the protection token in the symmetric binding and you also specify a callback handler, that accesses the database of UsernameToken credentials for authenticating clients.

Location of the STS Spring configuration

The STS Spring configuration file can be found in the following location:
CXFInstallDir/samples/sts/src/demo/wssec/sts/wssec-sts.xml

STS plug-in configuration

The first part of the wssec-sts.xml Spring configuration file is concerned with instantiating the STS implementation and specifying the relevant STS plug-ins to use:
<beans 
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:cxf="http://cxf.apache.org/core"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xmlns:test="http://apache.org/hello_world_soap_http"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
        http://cxf.apache.org/core
        http://cxf.apache.org/schemas/core.xsd
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://cxf.apache.org/jaxws                                     
        http://cxf.apache.org/schemas/jaxws.xsd
        http://www.springframework.org/schema/util
        http://www.springframework.org/schema/util/spring-util-2.0.xsd">
  ...
    <bean id="utSTSProviderBean"
        class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider">
        <property name="issueOperation" ref="utIssueDelegate"/>
        <property name="validateOperation" ref="utValidateDelegate"/>
    </bean>    

    <bean id="utIssueDelegate"
        class="org.apache.cxf.sts.operation.TokenIssueOperation">
        <property name="tokenProviders" ref="utSamlTokenProvider"/>
        <property name="services" ref="utService"/>
        <property name="stsProperties" ref="utSTSProperties"/>
    </bean>
    
    <bean id="utValidateDelegate"
        class="org.apache.cxf.sts.operation.TokenValidateOperation">
        <property name="tokenValidators" ref="utSamlTokenValidator"/>
        <property name="stsProperties" ref="utSTSProperties"/>
    </bean>
    
    <bean id="utSamlTokenProvider"
        class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
    </bean>
    
    <bean id="utSamlTokenValidator"
        class="org.apache.cxf.sts.token.validator.SAMLTokenValidator">
    </bean>
  ...
</beans>
In the demonstration STS instance, only two STS operations are supported: Issue, implemented by the utIssueDelegate bean, and Validate, implemented by the utValidateDelegate bean. The Validate operation is not used in the current demonstration.
The utIssueDelegate bean is configured with the following properties:
tokenProviders
A list of plug-ins that can generate various kinds of token. In this demonstration, this list is initialized with a single provider, SAMLTokenProvider, which is capable of generating SAML tokens.
services
(Optional) The services property enables you to specify the Web services that are secured by the STS, by specifying a list of regular expressions that must match the Web service URLs.
stsProperties
The stsProperties specifies some generic configuration settings that are common to many of the plug-ins in the STS.

STS signing key

The STS signing key—which is used to sign all of the tokens issued by the STS—is specified by setting the following properties on the StaticSTSProperties class:
signaturePropertiesFile
A WSS4J properties file that defines the properties for accessing the keys/stsstore.jks Java keystore file.
signatureUsername
The alias of the STS signing key in the Java keystore file.
callbackHandlerClass
A callback handler class that returns the password for accessing the STS signing key.
The StaticSTSProperties class is instantiated as the utSTSProperties bean in the wssec-sts.xml configuration file:
<beans ... >
    ...
    <bean id="utSTSProperties"
         class="org.apache.cxf.sts.StaticSTSProperties">
        <property name="signaturePropertiesFile" value="keys/stsKeystore.properties"/>
        <property name="signatureUsername" value="mystskey"/>
        <property name="callbackHandlerClass" value="demo.wssec.sts.STSCallbackHandler"/>
        <property name="issuer" value="DoubleItSTSIssuer"/>
    </bean>
    ...
</beans>

List of known Web service endpoints

The utService bean enables you to specify the Web service endpoints that are known to the STS, as follows:
<beans ... >
    ...
    <bean id="utService"
        class="org.apache.cxf.sts.service.StaticService">
        <property name="endpoints" ref="utEndpoints"/>
    </bean>
    
    <util:list id="utEndpoints">
        <value>http://localhost:(\d)*/SoapContext/SoapPort</value>
    </util:list>
    ...
</beans>
The utEndpoints bean instantiates a java.util.List object containing a list of regular expressions that must match the server's endpoint URL. When a client requests a new token from the STS, it includes the server's endpoint URL in the request, so that the STS can check whether or not the target endpoint is a known endpoint.
For more details about how to configure this, see Section 9.4, “Enabling AppliesTo in the STS”.

JAX-WS endpoint configuration

To create a HTTP/SOAP endpoint that listens for incoming connections to the STS, define a jaxws:element, as follows:
<beans ... >
  ...
    <jaxws:endpoint id="UTSTS"
        implementor="#utSTSProviderBean"
        address="http://localhost:8080/SecurityTokenService/UT" 
        wsdlLocation="wsdl/ws-trust-1.4-service.wsdl"
        xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
        serviceName="ns1:SecurityTokenService"
        endpointName="ns1:UT_Port">
        <jaxws:properties>
            <entry key="ws-security.callback-handler" value="demo.wssec.sts.STSCallbackHandler"/>
            <entry key="ws-security.signature.properties" value="keys/stsKeystore.properties"/>
            <entry key="ws-security.signature.username" value="mystskey"/>
        </jaxws:properties> 
    </jaxws:endpoint>
  ...
</beans>
In addition to the usual attributes required for a JAX-WS endpoint, the jaxws:endpoint element defines properties for accessing the protection token and a reference to a callback handler instance.

Protection token for the symmetric binding

The protection token provides the fundamental basis for the symmetric binding. It is used to generate all of the sessions keys for the connection. Although you might expect the corresponding properties to be called something like protection.token, the following properties of jaxws:endpoint are, in fact, used to specify the protection token:
ws-security.signature.properties
A WSS4J properties file that defines the properties for accessing the keys/stsstore.jks Java keystore file.
ws-security.signature.username
The alias of the protection token (X.509 certificate and private key pair) in the Java keystore file.
ws-security.callback-handler
A callback handler class that returns the password for accessing the protection token.
It so happens that in this demonstration, the protection token uses the same X.509 certificate and private key as the STS signing key.

STS callback handler

The jaxws:endpoint element is also configured with a callback handler (through the ws-security.callback-handler property), as follows:
// Java
package demo.wssec.sts;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class STSCallbackHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof WSPasswordCallback) {
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
                if ("mystskey".equals(pc.getIdentifier())) {
                    pc.setPassword("stskpass");
                    break;
                } else if ("alice".equals(pc.getIdentifier())) {
                    pc.setPassword("clarinet");
                    break;
                }
            }
        }
    }
}
The security callback handler can be used for multiple purposes (for example, see Providing Client Credentials). In particular, in this demonstration the callback handler on the jaxws:element is used for the following purposes:
  • Retrieving the password for the protection tokenthe protection token consists of a private key/public key pair and a password is needed to access the private key (which is stored in a Java keystore file).
  • Retrieving the password for a client's UsernameToken credentialsthe symmetric binding policy in this demonstration requires the client to send UsernameToken credentials to the STS, for the purpose of authenticating the client. The callback handler must therefore have access to a database of UsernameToken credentials, in order to authenticate the incoming UsernameToken credentials. In this example, just a single UsernameToken credential is supported, with username, alice, and password, clarinet.
    Note
    In an enterprise security system, it is more likely that you would use an LDAP server to store the client UsernameToken credentials.

9.2.4. Server WSDL Contract

Overview

The server WSDL contract determines the kind of security policies that are applied to the client-server connection. In the current demonstration, this connection is secured by an asymmetric binding policy.
A particularly important aspect of this policy is that the InitiatorToken is specified by an IssuedToken policy element. It is the presence of the IssuedToken element in the policy which triggers the client to call out to the STS, requesting the STS to issue a SAML token for single sign-on.

Location of the server WSDL contract

The server WSDL contract can be found in the following location:
CXFInstallDir/samples/sts/wsdl/hello_world.wsdl

Parts of the contract

The most important parts of the server WSDL contract are, as follows:
  • Greeter port type—a simple hello world interface consisting of a single WSDL operation, greetMe.
  • WSDL binding—the SOAP binding for the Greeter port type. Policies are enabled by applying them to various parts of the WSDL binding.
  • WSDL service and port—the WSDL port element specifies the address of the Greeter Web service endpoint.
  • Binding policy—a WS-Policy element that specifies how connections to the server must be secured.
  • Signed/encrypted parts policies—a WS-Policy element for input messages and a WS-Policy element for output messages, specifying which parts of the incoming SOAP messages and the outgoing SOAP messages must be signed and encrypted.

Greeter port type

The Greeter port type defines the logical interface to the Web service provided by the server, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="HelloWorld" targetNamespace="http://apache.org/hello_world_soap_http" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://apache.org/hello_world_soap_http"
    xmlns:x1="http://apache.org/hello_world_soap_http/types"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
    xmlns:wsp="http://www.w3.org/ns/ws-policy"
    xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"
    xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"
    xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512"
    xmlns:wsaw="http://www.w3.org/2005/08/addressing"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    ...
    <wsdl:portType name="Greeter">
        
        <wsdl:operation name="greetMe">
            <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
            <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
        </wsdl:operation>
        
    </wsdl:portType>
    ...
</wsdl:definitions>

Binding

The WSDL binding for the Greeter port type is a regular SOAP binding, except for the wsp:PolicyReference elements, which are used to apply the relevant security policies to the binding. Hence, the policy identified by AsymmetricSAML2Policy is applied to the whole binding and the Input_policy and the Output_policy are applied respectively to the input messages and the output messages of each operation.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
    ...
    <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
        <wsp:PolicyReference URI="#AsymmetricSAML2Policy" />
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        
        <wsdl:operation name="greetMe">
            <soap:operation soapAction="" style="document"/>
            <wsdl:input name="greetMeRequest">
                <soap:body use="literal"/>
                <wsp:PolicyReference URI="#Input_Policy" />
            </wsdl:input>
            <wsdl:output name="greetMeResponse">
                <soap:body use="literal"/>
                <wsp:PolicyReference URI="#Output_Policy" />
            </wsdl:output>
        </wsdl:operation>
        
    </wsdl:binding>
    ...
</wsdl:definitions>
For full details of how policy references work, see Policies and policy references.

Service and port

The WSDL service and WSDL port elements are used to define the address of the Greeter WS endpoint (specified by the location attribute of soap:address).
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
    ...
    <wsdl:service name="SOAPService">
        <wsdl:port binding="tns:Greeter_SOAPBinding" name="SoapPort">
            <soap:address location="http://localhost:9001/SoapContext/SoapPort"/>
        </wsdl:port>
    </wsdl:service>
    ...
</wsdl:definitions>

Binding policy

The binding policy, AsymmetricSAML2Policy, defines what kind of security is applied to incoming server connections.
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
    ...
    <wsp:Policy wsu:Id="AsymmetricSAML2Policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <wsam:Addressing wsp:Optional="false">
                    <wsp:Policy />
                </wsam:Addressing>
                <sp:AsymmetricBinding>
                    <wsp:Policy>
                        <sp:InitiatorToken>
                            <wsp:Policy>
                                <sp:IssuedToken
                                    sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                                    <sp:RequestSecurityTokenTemplate>
                                        <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
                                        <t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey</t:KeyType>
                                    </sp:RequestSecurityTokenTemplate>
                                    <wsp:Policy>
                                        <sp:RequireInternalReference />
                                    </wsp:Policy>
                                    <sp:Issuer>
                                        <wsaw:Address>http://localhost:8080/SecurityTokenService/
                                        </wsaw:Address>
                                    </sp:Issuer>
                                </sp:IssuedToken>
                            </wsp:Policy>
                        </sp:InitiatorToken>
                        <sp:RecipientToken>
                            <wsp:Policy>
                                <sp:X509Token
                                    sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never">
                                    <wsp:Policy>
                                        <sp:WssX509V3Token10 />
                                        <sp:RequireIssuerSerialReference />
                                    </wsp:Policy>
                                </sp:X509Token>
                            </wsp:Policy>
                        </sp:RecipientToken>
                        <sp:Layout>
                            <wsp:Policy>
                                <sp:Lax />
                            </wsp:Policy>
                        </sp:Layout>
                        <sp:IncludeTimestamp />
                        <sp:OnlySignEntireHeadersAndBody />
                        <sp:AlgorithmSuite>
                            <wsp:Policy>
                                <sp:Basic128 />
                            </wsp:Policy>
                        </sp:AlgorithmSuite>
                    </wsp:Policy>
                </sp:AsymmetricBinding>
                <sp:Wss11>
                    <wsp:Policy>
                        <sp:MustSupportRefIssuerSerial />
                        <sp:MustSupportRefThumbprint />
                        <sp:MustSupportRefEncryptedKey />
                    </wsp:Policy>
                </sp:Wss11>
                <sp:Trust13>
                    <wsp:Policy>
                        <sp:MustSupportIssuedTokens />
                        <sp:RequireClientEntropy />
                        <sp:RequireServerEntropy />
                    </wsp:Policy>
                </sp:Trust13>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    ...
</wsdl:definitions>
The binding policy defines the Greeter server security policy to be an asymmetric binding. This implies that security is applied at the SOAP message level, where parts of the SOAP payload are liable to be encrypted and/or signed. Because this is an asymmetric binding, two keys must be provided:
  • Initiator token—a SAML token, which has the client's X.509 certificate embedded inside it. Because the initiator token is defined to be an IssuedToken token, it is actually obtained by the querying the STS (using an STSClient object).
  • Recipient token—an X.509 certificate (public key) and private key pair, which is provided by the server side.
For a more detailed discussion of the asymmetric binding policy, see .

IssuedToken policy

Take a closer look at the IssuedToken policy, which is the IntiatorToken in the server's asymmetric binding. It is defined as follows:
<sp:IssuedToken
      sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
    <sp:RequestSecurityTokenTemplate>
        <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</t:TokenType>
        <t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/PublicKey</t:KeyType>
    </sp:RequestSecurityTokenTemplate>
    <wsp:Policy>
        <sp:RequireInternalReference />
    </wsp:Policy>
    <sp:Issuer>
        <wsaw:Address>http://localhost:8080/SecurityTokenService/</wsaw:Address>
    </sp:Issuer>
</sp:IssuedToken>
The IssuedToken policy is the key component of WS-Trust. It triggers the client to request an issued token from the STS. The sp:RequestSecurityTokenTemplate element specifies some elements that are to be included in the request that is sent to the STS. It includes the following elements:
<t:TokenType>...#SAMLV2.0</t:TokenType>
Indicates that the client wishes the STS to issue a SAML 2.0 token.
<t:KeyType>.../PublicKey</t:KeyType>
Indicates that the client wants the STS to support the Holder-of-Key scenario, where an X.509 certificate (public key) is used to verify the client identity. This implies that the client's X.509 certificate will be included in the request sent to the STS.

Signed parts and encrypted parts policies

The Input_policy policy is used to specify exactly which parts of an input message should be encrypted and/or signed by the asymmetric session keys (initiator token and recipient token). In addition to signing and encrypting the SOAP body, the standard WS-Addressing SOAP headers are also signed (which protects them from tampering by third-parties).
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
    ...
    <wsp:Policy wsu:Id="Input_Policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <sp:EncryptedParts>
                    <sp:Body />
                </sp:EncryptedParts>
                <sp:SignedParts>
                    <sp:Body />
                    <sp:Header ... />
                    ...
                </sp:SignedParts>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    ...
</wsdl:definitions>
The Output_policy policy is used to specify exactly which parts of an output message should be encrypted and/or signed by the asymmetric session keys (initiator token and recipient token).
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions ... >
    ...
    <wsp:Policy wsu:Id="Output_Policy">
        <wsp:ExactlyOne>
            <wsp:All>
                <sp:EncryptedParts>
                    <sp:Body />
                </sp:EncryptedParts>
                <sp:SignedParts>
                    <sp:Body />
                    <sp:Header ... />
                    ...
                </sp:SignedParts>
            </wsp:All>
        </wsp:ExactlyOne>
    </wsp:Policy>
    ...
</wsdl:definitions>

9.2.5. Server Configuration

Overview

Figure 9.7, “Demonstration Server Configuration” shows an overview of the configuration for the demonstration server.

Figure 9.7. Demonstration Server Configuration

Aspects of configuration

The most important aspects of the server configuration are, as follows:
  • WSDL contract and security policies—as already discussed in Section 9.2.4, “Server WSDL Contract”, the policies in the WSDL contract are used to define the type of security that protects incoming connections to the Greeter server.
  • JAX-WS endpoint configuration—in the JAX-WS endpoint you specify the X.509 certificate and private key that are used as the recipient token in the asymmetric binding and you also specify the certificate (or certificates) for checking the signature of a SAML token.
  • Recipient token—is specified by setting the relevant properties in the JAX-WS endpoint configuration.
  • Server-side SAML token interceptor—the SAML token interceptor checks the signature of the SAML token, using the X.509 certificates (public keys) stored in the keystore file referenced by the ws-security.encryption.properties property.
  • Server callback handler—is used to provide the passwords for private keys.
  • Related STS configuration—when setting up a new server, you must remember to add an appropriate regular expression to the list of known Web service endpoints in the STS, or the STS will refuse to perform any operations for this server.

JAX-WS endpoint configuration

To create a HTTP/SOAP endpoint that listens for incoming connections to the server, define a jaxws:element, as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:cxf="http://cxf.apache.org/core"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:sec="http://cxf.apache.org/configuration/security"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:httpj="http://cxf.apache.org/transports/http-jetty/configuration"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="
            http://cxf.apache.org/core
            http://cxf.apache.org/schemas/core.xsd 
            http://cxf.apache.org/configuration/security                
            http://cxf.apache.org/schemas/configuration/security.xsd
            http://cxf.apache.org/jaxws
            http://cxf.apache.org/schemas/jaxws.xsd
            http://cxf.apache.org/transports/http/configuration
            http://cxf.apache.org/schemas/configuration/http-conf.xsd
            http://cxf.apache.org/transports/http-jetty/configuration
            http://cxf.apache.org/schemas/configuration/http-jetty.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    ...
    <jaxws:endpoint id="server"
      implementor="demo.wssec.server.GreeterImpl"
      endpointName="s:SoapPort"
      serviceName="s:SOAPService"
      address="http://localhost:9001/SoapContext/SoapPort"
      wsdlLocation="wsdl/hello_world.wsdl"
      xmlns:s="http://apache.org/hello_world_soap_http">
        
      <jaxws:properties>
         <entry key="ws-security.signature.username" value="myservicekey"/>
         <entry key="ws-security.callback-handler" 
                value="demo.wssec.server.ServerCallbackHandler"/>
         <entry key="ws-security.signature.properties" value="keys/serviceKeystore.properties"/>
         <entry key="ws-security.encryption.properties" value="keys/serviceKeystore.properties"/>
      </jaxws:properties> 
    </jaxws:endpoint>
    ...
</beans>
In addition to the usual attributes required for a JAX-WS endpoint, the jaxws:endpoint element defines properties for accessing the recipient token, properties for accessing SAML signature-checking tokens, and a reference to a callback handler instance.

Recipient token

The recipient token for the asymmetric binding has both a public key part (used for encrypting outgoing messages) and a private key part (used for signing outgoing messages). These parts of the recipient token are specified by the following properties on the server's jaxws:endpoint element:
ws-security.signature.properties
A WSS4J properties file that defines the properties for accessing the private key part of the recipient token.
ws-security.signature.username
The alias of the recipient token (X.509 certificate and private key pair) in the Java keystore file.
ws-security.callback-handler
A callback handler class that returns the password for accessing the private key part of the recipient token.
ws-security.encryption.properties
A WSS4J properties file that defines the properties for accessing the public key part of the recipient token.

Server-side SAML token interceptor

The SAML token interceptor is automatically installed in the server, whenever the corresponding security policy is configured to use the IssuedToken policy. The SAML token interceptor is responsible for verifying the signature of the SAML token received from the client (initiator token).
Hence, it is necessary to configure one or more trusted certificates that can be used to check the signature of the SAML token. The SAML token will be rejected unless it is signed by one of the specified trusted certificates.
As it happens, there is not a dedicated property for specifying these trusted certificates. Instead, the SAML token interceptor re-uses the ws-security.encryption.properties property. Any trusted certificates found in the Java keystore file specified by ws-security.encryption.properties will be used for checking the signature of the SAML token. The configuration of the SAML token interceptor is thus the very same configuration that was used to specify the public key part of the recipient token:
<jaxws:endpoint ... >
  
  <jaxws:properties>
    ...
    <entry key="ws-security.encryption.properties" value="keys/serviceKeystore.properties"/>
  </jaxws:properties> 
</jaxws:endpoint>
In practice, configuring the SAML token interceptor consists of using a Java keystore utility to add the trusted STS X.509 certificate to the Java keystore file that is referenced by ws-security.encryption.properties.

Server callback handler

The jaxws:endpoint element is also configured with a callback handler (through the ws-security.callback-handler property), as follows:
// Java
package demo.wssec.server;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class ServerCallbackHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof WSPasswordCallback) { // CXF
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
                if ("myservicekey".equals(pc.getIdentifier())) {
                    pc.setPassword("skpass");
                    break;
                }
            }
        }
    }
}
In this case, the security callback handler is used solely for the purpose of retrieving the password for accessing the private key part of the recipient token (which has the alias, myservicekey).

Related STS configuration

When setting up a server, you must remember to add an appropriate regular expression to the list of known Web service endpoints in the STS. For example, as discussed in the context of configuring the STS, you need to include a regular expression that matches the server's endpoint URL, which is set in the wssec-sts.xml file as follows:
<beans ... >
    ...
    <bean id="utService"
        class="org.apache.cxf.sts.service.StaticService">
        <property name="endpoints" ref="utEndpoints"/>
    </bean>
    
    <util:list id="utEndpoints">
        <value>http://localhost:(\d)*/SoapContext/SoapPort</value>
    </util:list>
    ...
</beans>

9.2.6. Client Configuration

Overview

Figure 9.8, “Demonstration Client Configuration” shows an overview of the configuration for the demonstration client.

Figure 9.8. Demonstration Client Configuration

Aspects of configuration

The most important aspects of the client configuration are, as follows:
  • Configure the connection to the STS (STSClient)—the client uses an STSClient instance to connect to the STS. The STSClient instance is a complete client in itself, requiring you to specify the STS Web service address and to specify the relevant security properties for the connection.
  • Configure the connection to the server—the client must also be configured to connect to the server, including the relevant security properties for the connection and a reference to the STSClient instance.
  • Client callback handler—is used to provide the passwords for private keys and to provide the passwords for UsernameToken credentials.
  • Related STS configuration—you must ensure that the client's UsernameToken credentials are made available to the STS, so that the client can be authenticated.

Configure the connection to the STS

You must configure the client so that it is capable of contacting the STS to retrieve an issued SAML token. To enable the STS connection, initialize the client's ws-security.sts.client property with an STSClient instance, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:cxf="http://cxf.apache.org/core"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:sec="http://cxf.apache.org/configuration/security"
  xmlns:http="http://cxf.apache.org/transports/http/configuration"
  xmlns:jaxws="http://cxf.apache.org/jaxws"
  xsi:schemaLocation="
           http://cxf.apache.org/core
           http://cxf.apache.org/schemas/core.xsd
           http://cxf.apache.org/configuration/security
           http://cxf.apache.org/schemas/configuration/security.xsd
           http://cxf.apache.org/jaxws
           http://cxf.apache.org/schemas/jaxws.xsd
           http://cxf.apache.org/transports/http/configuration
           http://cxf.apache.org/schemas/configuration/http-conf.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd">
    ...
    <jaxws:client name="{http://apache.org/hello_world_soap_http}SoapPort"
                  createdFromAPI="true">
       <jaxws:properties>
           ...
           <entry key="ws-security.sts.client">
               <bean class="org.apache.cxf.ws.security.trust.STSClient">
                   <constructor-arg ref="cxf"/>
                   <property name="wsdlLocation" 
                             value="http://localhost:8080/SecurityTokenService/UT?wsdl"/>
                   <property name="serviceName" 
                             value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}SecurityTokenService"/>
                   <property name="endpointName" 
                             value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}UT_Port"/>
                   <property name="properties">
                       <map>
                           <entry key="ws-security.username" value="alice"/>
                           <entry key="ws-security.callback-handler" 
                                  value="demo.wssec.client.ClientCallbackHandler"/>
                           <entry key="ws-security.encryption.properties"
                                  value="keys/clientKeystore.properties"/> 
                           <entry key="ws-security.encryption.username" value="mystskey"/>
                           <entry key="ws-security.sts.token.username" value="myclientkey"/>
                           <entry key="ws-security.sts.token.properties"
                                  value="keys/clientKeystore.properties"/> 
                           <entry key="ws-security.sts.token.usecert" value="true"/> 
                       </map>
                   </property>
               </bean>            
           </entry> 
       </jaxws:properties>
   </jaxws:client>
    ...
</beans>
Besides the usual properties required for connecting to a Web service endpoint (specified by the wsdlLocation, serviceName, and endpointName properties), you must set the following security-related properties:
ws-security.username
In this demonstration, the STS is configured to authenticate the client using UsernameToken credentials. This property specifies the username part of the UsernameToken credentials.
ws-security.callback-handler
The callback handler class provides both private key passwords and UsernameToken passwords.
ws-security.encryption.properties
A WSS4J properties file that defines the properties for accessing the STS X.509 certificate. This certificate is needed by the symmetric binding protocol, which uses it to generate a symmetric session key.
ws-security.encryption.username
The alias of the X.509 certificate referenced by ws-security.encryption.properties.
ws-security.sts.token.properties
A WSS4J properties file that defines the properties for accessing the client's X.509 certificate. This is the certificate that is used to identify the client to the server in the Holder-of-Key scenario. This token gets embedded in the request that is sent to the STS (and is also embedded in the SAML token returned from the STS).
ws-security.sts.token.username
The alias of the STS X.509 certificate referenced by ws-security.sts.token.properties.
ws-security.sts.token.usecert
Setting this boolean property to true indicates that the specified token should be included in the request sent to the STS (the RequestSecurityToken message).

Configure the connection to the server

To configure the connection to the server, set the relevant properties directly on the JAX-WS client bean, as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans ... >
    ...
    <jaxws:client name="{http://apache.org/hello_world_soap_http}SoapPort" createdFromAPI="true">
       <jaxws:properties>
           <entry key="ws-security.signature.properties" value="keys/clientKeystore.properties"/>
           <entry key="ws-security.signature.username" value="myclientkey"/>
           <entry key="ws-security.callback-handler" 
                  value="demo.wssec.client.ClientCallbackHandler"/>
           <entry key="ws-security.encryption.properties" value="keys/clientKeystore.properties"/> 
           <entry key="ws-security.encryption.username" value="myservicekey"/>
           <entry key="ws-security.sts.client">
               <bean class="org.apache.cxf.ws.security.trust.STSClient">
                   ...
               </bean>            
           </entry> 
       </jaxws:properties>
   </jaxws:client>
    ...
</beans>
Because the client-server connection uses an asymmetric binding (with an issued token), the following aspects of security need to be configured.
Configure the client's signing key (also used for decrypting message parts received from the server), using the following properties:
ws-security.signature.properties
A WSS4J properties file that defines the properties for accessing the client's signing key.
ws-security.signature.username
The alias of the client's signing key in the corresponding Java keystore file.
ws-security.callback-handler
The callback handler instance that can return the password for accessing the client's signing key.
Configure the client's encryption key (also used for verifying signatures on message parts received from the server), using the following properties:
ws-security.encryption.properties
A WSS4J properties file that defines the properties for accessing the client's encryption key (X.509 certificate).
ws-security.encryption.username
The alias of the client's encryption key in the corresponding Java keystore file.
Configure the client to support the IssuedToken policy by setting the ws-security.sts.client property, as already described in the section called “Configure the connection to the STS”.

Client callback handler

The client callback handler class is multi-purpose. It is capable of returning both passwords for private keys and the password part of UsernameToken credentials. In this demonstration, the client callback handler class is defined as follows:
// Java
package demo.wssec.client;

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.ws.security.WSPasswordCallback;

public class ClientCallbackHandler implements CallbackHandler {

    public void handle(Callback[] callbacks) throws IOException,
            UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            if (callbacks[i] instanceof WSPasswordCallback) {
                WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
                if ("myclientkey".equals(pc.getIdentifier())) {
                    pc.setPassword("ckpass");
                    break;
                } else if ("alice".equals(pc.getIdentifier())) {
                    pc.setPassword("clarinet");
                    break;
                } else if ("bob".equals(pc.getIdentifier())) {
                    pc.setPassword("trombone");
                    break;
                } else if ("eve".equals(pc.getIdentifier())) {
                    pc.setPassword("evekpass");
                    break;
                }
            }
        }
    }
}

Related STS configuration

In this demonstration, the STS authenticates the client by checking the client's UsernameToken credentials. Hence, you must ensure that the client's UsernameToken credentials are known to the STS. In this demonstration, the known UsernameToken credentials are embedded in the code of the STS callback handler class, the section called “STS callback handler ”.

9.2.7. Build and Run the Demonstration

Steps to run the demonstration

To build and run the STS demonstration, perform the following steps:
  1. Open a command prompt and change directory to the CXFInstallDir/samples/sts directory. Enter the following command to build the demonstration:
    mvn clean install
  2. To start the STS process, enter the following command:
    mvn -Psts
  3. To start the WS server process, open a new command prompt, change directory to the CXFInstallDir/samples/sts directory, and enter the following command:
    mvn -Pserver
  4. To run the WS client, open a new command prompt, change directory to the CXFInstallDir/samples/sts directory, and enter the following command:
    mvn -Pclient
    Because CXF logging has been enabled, you should see the SOAP messages being logged to each of the command windows. If the client runs successfully, you should see the following message in the client command window:
    ...
    --------------------------------------
    Server responded with: Hello YourName