Latest Activity

Apache CXF STS articles

Colm O hEigeartaigh - Tue, 10/11/2011 - 15:21
Two of my colleagues have written excellent articles on the forthcoming STS (Security Token Service) implementation in Apache CXF, complete with sample projects. See here for the article from Oliver Wulff, and here for the article from Glen Mazza.
Categories: Colm O hEigeartaigh

Adding UsernameToken security headers in Metro

Glen Mazza - Tue, 10/11/2011 - 13:00

This tutorial modifies the Metro version of the WSDL-first DoubleIt Example to include WS-Security with the UsernameToken profile. Metro requires transport-level encryption (i.e., SSL) or other message-level encryption to be in use while using this profile. Also be careful not to confuse UsernameToken with the separate and distinct basic authentication over SSL method.

Metro specifies WS-Security/UsernameTokens using WS-SecurityPolicy assertions, either directly in the WSDL (for WSDL-first web services) or in a separate configuration file (for Java-first services). WS-SecurityPolicy configuration is rather complex and so the Metro team recommends using the NetBeans IDE to generate this configuration, which we'll be doing here. The instructions below will show how to integrate the policy files created by NetBeans back into the Maven-based DoubleIt project.

For username/password resolution, Metro provides two options for service-side authentication: JEE/servlet-container based (e.g., validating against usernames and passwords stored in the tomcat-users.xml file), or via a service-side validation handler which allows you more options such as accessing an external data store for validation. Both options are covered below for Tomcat.

The finished source code for this tutorial is downloadable here.

  1. Implement SSL without basic authentication for the web service. Follow the SSL tutorial for this, except with the following changes:

    • Change Step #4 to just require SSL without basic auth by making the below web.xml modification. <security-constraint> <web-resource-collection> <web-resource-name>restricted web services</web-resource-name> <url-pattern>/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint>
    • Skip Step #5 if you plan on validating users using a service-side callback handler instead of users defined within your servlet or JEE container.
    • Skip Step #10 because we're no longer providing basic auth information (the basic DoubleIt Client class can be used as-is.)

    Make sure the SOAP client works against the SSL-hosted web service before continuing.

  2. Update your JDK's JAX-WS and JAXB libraries. Netbeans requires the newer 2.2.x version of JAX-WS (jaxws-api.jar) not provided by default in Java SE 6. See here for more information on placing this new JAR in your JDK's endorsed folder.

  3. Modify the WSDL to require the UsernameToken profile. To do this, we will create a temporary project in NetBeans and use it to add the WS-SecurityPolicy elements to our DoubleIt.wsdl file. (Recommend always using the latest release version of NetBeans, as updates to its WSIT support occur frequently.) We'll then place the modified WSDL back into our Maven project. Steps:

    1. From the NetBeans Menu Bar, Choose File | New Project. From the Java Web category, choose Web Application. Choose Tomcat 7.0 as the Server (OK if you're using Tomcat 6.x, we're just making this project to get the security-enhanced WSDL) and Java EE 6 Web for the Java EE version. Accept the rest of the defaults.

    2. From the NetBeans Projects view, right click the new project you created and select New | Web Service From WSDL. Browse for the DoubleIt.wsdl file used in the WSDL-first tutorial and select it. Enter any package name--we won't be using the generated artifacts so what you place here won't matter. Click Finish, and "Yes" to the subsequent question of whether you want to use the sun-jaxws.xml configuration file in lieu of JSR-109 deployment. Note in creating the web service, NetBeans will make its own copy of the WSDL that can be seen in the Project View under Configuration Files/xml-resources/Web Services.

    3. From the Projects View, right-click the Web Application -> Web Services -> DoubleItService entry and select "Edit Web Service Attributes". From the pop-up that appears (see picture below), select the Quality of Service tab. From here:

      • For Version Compatibility, choose the latest version offered. Note the Metro 2.1 JARs support all versions offered. This field refers not to the Metro JARs that will be used but primarily the version of the WS-Policy namespaces that will be generated.
      • Check the "Secure Service" checkbox and choose "Message Authentication over SSL" as the Security Mechanism. If you wish to use a service-side validation handler (and not usernames defined within your app server), unselect Use Development Defaults, press the Validators button and enter "service.PlainTextPasswordValidator" as the Username Validator.
      • Select the Configure button to the right of the Security Mechanism field and choose Username Token and WSS Version 1.1. The remaining options can be left as-is (although advisable to use a more vigorous encryption algorithm such as 256-bit encryption for production use.) Hit "OK" and the project's copy of the WSDL will be altered with the Policy statements giving the new security requirements.
    4. From the Projects View, go to Web Application -> Configuration Files -> xml-resources, and drill down to the DoubleIt.wsdl file. Make sure it has the wsp:Policy element at the bottom. Save this DoubleIt.wsdl file back to the Mavenized project, replacing the original DoubleIt.wsdl file in service/src/main/resources.

      The resulting modified WSDL is shown below. A new Policy element has been added at the end, as well a policy reference to that element within the wsdl:binding section. The policy element contains a UsernameToken Assertion section indicating that this profile is to be used for all SOAP requests. (Note the ValidatorConfiguration element in the Policy section will be present only if you configured a validation handler--if later switching to app server-maintained usernames and passwords be sure to remove this element.)

      <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="DoubleIt" xmlns:xsd="" xmlns:wsdl="" xmlns:soap="" xmlns:di="" xmlns:tns="" targetNamespace="" xmlns:wsp="" xmlns:wsu="" xmlns:fi="" xmlns:tcp="" xmlns:wsam="" xmlns:sp="" xmlns:sc="" xmlns:wspp=""> <wsdl:types> <xsd:schema targetNamespace=""> <xsd:element name="DoubleIt"> <xsd:complexType> <xsd:sequence> <xsd:element name="numberToDouble" type="xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="DoubleItResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="doubledNumber" type="xsd:int" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="DoubleItRequest"> <wsdl:part element="di:DoubleIt" name="parameters" /> </wsdl:message> <wsdl:message name="DoubleItResponse"> <wsdl:part element="di:DoubleItResponse" name="parameters" /> </wsdl:message> <wsdl:portType name="DoubleItPortType"> <wsdl:operation name="DoubleIt"> <wsdl:input message="tns:DoubleItRequest" /> <wsdl:output message="tns:DoubleItResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="DoubleItBinding" type="tns:DoubleItPortType"> <wsp:PolicyReference URI="#DoubleItBindingPolicy"/> <soap:binding style="document" transport="" /> <wsdl:operation name="DoubleIt"> <soap:operation soapAction=""/> <wsdl:input><soap:body use="literal"/> </wsdl:input> <wsdl:output><soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="DoubleItService"> <wsdl:port name="DoubleItPort" binding="tns:DoubleItBinding"> <soap:address location="https://localhost:8443/doubleit/services/doubleit"/> </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <wsam:Addressing wsp:Optional="false"/> <sp:TransportBinding> <wsp:Policy> <sp:TransportToken> <wsp:Policy> <sp:HttpsToken RequireClientCertificate="false"/> </wsp:Policy> </sp:TransportToken> <sp:Layout> <wsp:Policy> <sp:Lax/> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp/> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic128/> </wsp:Policy> </sp:AlgorithmSuite> </wsp:Policy> </sp:TransportBinding> <sp:SignedEncryptedSupportingTokens> <wsp:Policy> <sp:UsernameToken sp:IncludeToken=""> <wsp:Policy> <sp:WssUsernameToken10/> </wsp:Policy> </sp:UsernameToken> </wsp:Policy> </sp:SignedEncryptedSupportingTokens> <sc:ValidatorConfiguration wspp:visibility="private"> <sc:Validator name="usernameValidator" classname="service.PlainTextPasswordValidator"/> </sc:ValidatorConfiguration> <sp:Wss11/> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </wsdl:definitions>

      This modified WSDL will be used both by the service provider and the SOAP client in our project--the service because this WSDL is the one specified for it, while the client reads it by default because it is hardcoded in by the generated JAX-WS class. As a result, the policy information in the WSDL will activate security behavior on both sides--the service will require username tokens for SOAP requests and the client will supply those tokens when making SOAP calls.

      More information on configuring WS-Security with Metro is available in the Metro User's Guide, chapters 12-14 in particular.

  4. Create the service-side username and password validation handler. If you are relying on usernames and passwords defined within your application container, skip this step. Otherwise, create the following PlainTextPasswordValidator class and place it in the service/src/main/java/service directory: package service; import com.sun.xml.wss.impl.callback.PasswordValidationCallback; public class PlainTextPasswordValidator implements PasswordValidationCallback.PasswordValidator { public boolean validate(PasswordValidationCallback.Request request) throws PasswordValidationCallback.PasswordValidationException { PasswordValidationCallback.PlainTextPasswordRequest plainTextRequest = (PasswordValidationCallback.PlainTextPasswordRequest) request; if ("alice".equals(plainTextRequest.getUsername()) && "clarinet".equals(plainTextRequest.getPassword())) { return true; } else if ("bob".equals(plainTextRequest.getUsername()) && "trombone".equals(plainTextRequest.getPassword())) { return true; } return false; } }

    You can also validate against usernames and passwords stored in a database or other external lookup facility. For sample (if unrelated) code, this blog entry shows a simple way of accessing a database from a web service provider.

  5. Configure the client to send UsernameToken authentication data. As described in the WSIT documentation, NetBeans generates two client-side configuration files: wsit-client.xml and {wsdl file name}.xml. However, the former imports the latter and together these two files are simply a copy of the service WSDL with its wsp:Policy element modified to provide client-side configuration data. When a Metro-based SOAP client runs, it merges the policy information between the wsit-client.xml and the service's WSDL (by default, the WSDL file whose location is hardcoded in the JAX-WS generated DoubleItService class) in order to determine the full security requirements.

    NetBeans can be used to generate the client config files, or you can create the wsit-client.xml file manually from the service's WSDL--use either option as described below.

    Process for NetBeans creation of client-side config file:

    1. From the NetBeans project you created in the previous step, right-click the project title in the Projects view and select New->Web Service Client.
    2. For the New Web Service Client pop-up, two fields need populating. For the client package name, any entry will do (this information will not be used later). For the WSDL location, select "Local file" and choose the WSDL that has the WS:Policy elements you just added above. (Right-clicking the WSDL in the NetBeans project view under Configuration Files -> xml-resources -> web-services and selecting "properties" will give you the WSDL's precise location.) NetBeans reads the policy elements to determine the client-side security features needed.
    3. Next we will need to specify how we will be supplying usernames and passwords to the service. We have a choice of hardcoding or providing username and password callback handlers. Within the Project View of the project, go to Web Service References -> DoubleIt, and right-click on the latter. Choose "Edit Web Service Attributes". On the Quality of Service Tab, Security Section (see picture below), choose "Dynamic" for Authentication Credentials. For the Username and Password Callback handlers, enter "client.MyCallbackHandler" for both.

      The resulting client configuration files will be located in the Source Packages -> META-INF folder of the Project View. They are shown below:

      wsit-client.xml: <?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="" xmlns:wsdl="" xmlns:xsd="" xmlns:soap="" name="mainclientconfig" > <import location="DoubleIt.xml" namespace=""/> </definitions>

      DoubleIt.xml - As stated earlier, this is just the service WSDL except that the Policy section at the bottom has changed from providing service-side requirements to client-side configuration information.

      <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="DoubleIt" xmlns:xsd="" xmlns:wsdl="" xmlns:soap="" xmlns:di="" xmlns:tns="" targetNamespace="" xmlns:wsp="" xmlns:wsu="" xmlns:fi="" xmlns:tcp="" xmlns:wsam="" xmlns:sp="" xmlns:sc="" xmlns:wspp="" xmlns:sc1=""> <wsdl:types> <xsd:schema targetNamespace=""> <xsd:element name="DoubleIt"> <xsd:complexType> <xsd:sequence> <xsd:element name="numberToDouble" type="xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="DoubleItResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="doubledNumber" type="xsd:int" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="DoubleItRequest"> <wsdl:part element="di:DoubleIt" name="parameters" /> </wsdl:message> <wsdl:message name="DoubleItResponse"> <wsdl:part element="di:DoubleItResponse" name="parameters" /> </wsdl:message> <wsdl:portType name="DoubleItPortType"> <wsdl:operation name="DoubleIt"> <wsdl:input message="tns:DoubleItRequest" /> <wsdl:output message="tns:DoubleItResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="DoubleItBinding" type="tns:DoubleItPortType"> <wsp:PolicyReference URI="#DoubleItBindingPolicy"/> <soap:binding style="document" transport="" /> <wsdl:operation name="DoubleIt"> <soap:operation soapAction=""/> <wsdl:input><soap:body use="literal"/> </wsdl:input> <wsdl:output><soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="DoubleItService"> <wsdl:port name="DoubleItPort" binding="tns:DoubleItBinding"> <soap:address location="https://localhost:8443/doubleit/services/doubleit"/> </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <sc1:CallbackHandlerConfiguration wspp:visibility="private"> <sc1:CallbackHandler name="usernameHandler" classname="client.MyCallbackHandler"/> <sc1:CallbackHandler name="passwordHandler" classname="client.MyCallbackHandler"/> </sc1:CallbackHandlerConfiguration> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </wsdl:definitions>

      Note if during the client-side login configuration you chose "static" (i.e., hardcoded username and password) instead of "dynamic", the ending Policy section of the above file will be as below. It can be useful to temporarily switch to static configuration for troubleshooting authentication problems.

      ... </wsdl:service> <wsp:Policy wsu:Id="DoubleItBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <sc1:CallbackHandlerConfiguration wspp:visibility="private"> <sc1:CallbackHandler name="usernameHandler" default="alice" /> <sc1:CallbackHandler name="passwordHandler" default="clarinet" /> </sc1:CallbackHandlerConfiguration> </wsp:All> </wsp:ExactlyOne> </wsp:Policy>
    4. Copy the two configuration files above back to the DoubleIt Maven project, placing them in client/src/main/resources.

    Process for manual creation of the client-side config file: Copy the updated web service WSDL into a new wsit-client.xml file. Remove its service-side wsp:Policy statement and replace it a client-side wsp:Policy element similar to the one in the DoubleIt.xml file shown above (either the callback handler or hardcoded username/password version). Place this wsit-client.xml file in the client's resources folder mentioned above.

  6. Create the client-side MyCallbackHandler to supply the username and password. Place the following class in the same package as the SOAP client--see the CallbackHandler javadoc for more details about this class.

    package client; import; import; import; import; import; import; public class MyCallbackHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nc = (NameCallback) callbacks[i]; nc.setName("alice"); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback) callbacks[i]; pc.setPassword("clarinet".toCharArray()); } else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); } } } }
  7. Test the client. First, redeploy the web service provider (mvn clean install tomcat:redeploy). Next, using a terminal window navigate to the client directory and enter mvn exec:exec. You should see the same output as from the previous tutorial. Best to test also with bad usernames, passwords, etc., to ensure the web service provider is catching these errors.

    You can see the unencrypted SOAP request and response by activating the debug output as shown in the comments for the exec-maven-plugin in the client/pom.xml file. My results:

    ---[HTTP request - https://localhost:8443/doubleit/services/doubleit]--- Accept: text/xml, multipart/related Content-Type: text/xml; charset=utf-8 SOAPAction: "" User-Agent: Metro/2.1 (branches/2.1-6728; 2011-02-03T14:14:58+0000) JAXWS-RI/2.2.3 JAXWS/2.2 <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S="" xmlns:wsse11="" xmlns:wsse="" xmlns:wsu="" xmlns:xs=""> <S:Header> <To xmlns="">https://localhost:8443/doubleit/services/doubleit</To> <Action xmlns="" xmlns:S="" S:mustUnderstand="1"></Action> <ReplyTo xmlns=""> <Address></Address> </ReplyTo> <MessageID xmlns="">uuid:93e0c133-f54b-47ab-bcce-4d7dfdd71f53</MessageID> <wsse:Security S:mustUnderstand="1"> <wsu:Timestamp xmlns:ns15="" xmlns:ns14="" wsu:Id="_1"> <wsu:Created>2011-10-17T00:21:08Z</wsu:Created> <wsu:Expires>2011-10-17T00:26:08Z</wsu:Expires> </wsu:Timestamp> <wsse:UsernameToken xmlns:ns15="" xmlns:ns14="" wsu:Id="uuid_7a42ed86-83c0-42ab-ab09-2c2cb6483297"> <wsse:Username>alice</wsse:Username> <wsse:Password Type="">clarinet</wsse:Password> </wsse:UsernameToken> </wsse:Security> </S:Header> <S:Body> <ns2:DoubleIt xmlns:ns2=""> <numberToDouble>10</numberToDouble> </ns2:DoubleIt> </S:Body> </S:Envelope> -------------------- ---[HTTP response - https://localhost:8443/doubleit/services/doubleit - 200]--- null: HTTP/1.1 200 OK Content-Type: text/xml;charset=utf-8 Date: Mon, 17 Oct 2011 00:21:08 GMT Server: Apache-Coyote/1.1 Transfer-Encoding: chunked <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S="" xmlns:wsse11="" xmlns:wsse="" xmlns:wsu="" xmlns:xs=""> <S:Header> <To xmlns=""></To> <Action xmlns="" xmlns:S="" S:mustUnderstand="1"></Action> <MessageID xmlns="">uuid:d02f4957-1dfe-41b5-9640-eec9ee441b98</MessageID> <RelatesTo xmlns="">uuid:93e0c133-f54b-47ab-bcce-4d7dfdd71f53</RelatesTo> <wsse:Security S:mustUnderstand="1"> <wsu:Timestamp xmlns:ns15="" xmlns:ns14="" wsu:Id="_1"> <wsu:Created>2011-10-17T00:21:08Z</wsu:Created> <wsu:Expires>2011-10-17T00:26:08Z</wsu:Expires> </wsu:Timestamp> </wsse:Security> </S:Header> <S:Body> <ns2:DoubleItResponse xmlns:ns2=""> <doubledNumber>20</doubledNumber> </ns2:DoubleItResponse> </S:Body> </S:Envelope> -------------------- The number 10 doubled is 20

    As the username and password is being sent in cleartext in the SOAP request, be sure to confirm your endpoint URL is using HTTPS/SSL to encrypt the messages during production (which will probably be enforced by default with Metro, as stated earlier.) Wireshark is a good tool to inspect the SOAP requests and responses being sent over the wire.


  • If you're using a service-side username validation handler, you may see a warning message similar to the following when running the client:

    WARNING: WSP0075: Policy assertion "{}ValidatorConfiguration" was evaluated as "UNSUPPORTED". Oct 16, 2011 8:19:07 PM [] selectAlternatives WARNING: WSP0019: Suboptimal policy alternative selected on the client side with fitness "PARTIALLY_SUPPORTED".

    This warning is a consequence of the client and the service provider sharing the same physical WSDL file in this tutorial (due to the hardcoded reference to the WSDL file in the class used by both service and client). This results in the client trying to process the service-specific policy statements in the WSDL and reporting warnings that it (of course) cannot do so. Normally, in production environments, SOAP clients will use a copy of the service's WSDL from the browser in generating the JAX-WS artifacts, instead of the service's internal copy. The browser-based WSDL will not have the service-side keystore information (due to the default wspp:visibility="private" setting in the WSDL) and hence running clients will not generate these warning messages.

  • Alternative tutorial: Java Web services: WS-Security with Metro - IBM developerWorks article by Dennis Sosnoski (December 2009)

Configure and deploy CXF 2.5 STS - Part I

Oliver Wulff - Tue, 10/11/2011 - 10:11
Talend has donated an STS implementation to the Apache CXF community as posted already on this here

This is the first part of a series of blogs on using WS-Federation Passive Requestor Profile to implement a Web and Web Services SSO solution from a web application to a target Web Service. The used technologies are CXF 2.5 (to be released soon) and Tomcat 7.

  • Part I
    Configure and deploy CXF STS using Claims
  • Part II
    Configure and deploy Identity Provider (IdP)
  • Part III
    Configure and deploy Tomcat Relying Party (RP)
  • Part IV
    Enhance Tomcat RP to call a target web services which delegates the identity
  • Part V
    Interoperability testing with Microsoft Windows Identity Foundation

The STS in this part is configured to support the following functionality:
  • STS WSDL is enriched with the WS-SecurityPolicy information
  • STS issues a signed SAML 2.0 token
  • STS is secured using HTTPS
  • STS validates an incoming UsernameToken against a local file store
  • STS adds claims information to the SAML token in an attribute statement
You can find a running maven project here.

1. Username and password management

The users and passwords are configured in a spring configuration file in WEB-INF/passwords.xml. The XML file has the following structure:

    <util:map id="passwords">
        <entry key="alice"
            value="ecila" />
        <entry key="bob"
            value="bob" />
        <entry key="ted"
            value="det" />

The intention of this STS example is to illustrate how to set up an STS. If you have an LDAP directory in place or any other JAAS based LoginModule you can also plug in the WSS4J JAASUsernameTokenValidator.

2. Claims management

The claims for each user are configured in a spring configuration file also in WEB-INF/userClaims.xml. The XML file has the following structure:

    <util:map id="userClaims">
        <entry key="alice"
            value-ref="aliceClaims" />
        <entry key="bob"
            value-ref="bobClaims" />
        <entry key="ted"
            value-ref="tedClaims" />
    <util:map id="aliceClaims">
        <entry key=""
            value="Alice" />
        <entry key=""
            value="Smith" />
        <entry key=""
            value="" />
        <entry key=""
            value="user" />

The claim id's are configured according to chapter 7.5 in the specification Identity Metasystem Interoperability. The mapping of claims to a SAML attribute statement are described in chapter 7.2.
There is no standard URI for role. Therefore, I reuse Microsoft's role URI which is used by ADFS (Active Directory Federation Service) and Windows Identity Foundation (WIF). If the STS issues claims using the same role URI, you get role-based access control (or claims based authorization support for WIF based applications out-of-the-box).

The intention of this STS example is to illustrate how to set up an STS. If you have an LDAP directory in place you can configure the LdapClaimsHandler where you configure the mapping of the claim id (URI) to an LDAP user attribute. 

3. Project dependencies
The STS has the following dependencies in the Maven project.

   <dependencies>        <dependency>

4. STS endpoint configuration

Setting up the STS involves several steps. The STS is configured using the spring framework. First step is to download Tomcat 7.

4.1 Configure HTTP/S connector in Tomcat

The HTTP connector should be configured with port 9080.

The HTTPS connector in Tomcat is configured in conf/server.xml. Deploy the tomcatkeystore.jks of the example project  to the Tomcat root directory if the Connector is configured as illustrated:

    <Connector port="9443" protocol="HTTP/1.1" SSLEnabled="true"
               maxThreads="150" scheme="https" secure="true"
               keystorePass="tompass" sslProtocol="TLS" />
This connector configures a self-signed certificate which is used for simplification only. You should get a certificate signed by a Certificate Authority for production usage.

4.2 Configure the WS-SecurityPolicies of the STS endpoint

The following policies must be added to the WSDL. CXF provides other ways to correlate policies with a wsdl subject (port type, service, port, ...). I've chosen the simplest one where the policies are embedded into the wsdl for illustration purposes. The WSDL can be found in WEB-INF/wsdl/ws-trust-1.4-service.wsdl

The following policy defines a transport binding (https) and expects a UsernameToken be present in the WS-Security header. The UsernameToken must be signed which is implicitly supported by HTTPS:

    <wsp:Policy wsu:Id="Transport_policy">
                        <sp:HttpsToken RequireClientCertificate="false"/>
                        <sp:TripleDesRsa15 />
                        <sp:Lax />
                  <sp:IncludeTimestamp />
                        <sp:WssUsernameToken10 />
                  <sp:MustSupportRefKeyIdentifier />
                  <sp:MustSupportRefIssuerSerial />
                  <sp:MustSupportRefThumbprint />
                  <sp:MustSupportRefEncryptedKey />
                  <sp:MustSupportIssuedTokens />
                  <sp:RequireClientEntropy />
                  <sp:RequireServerEntropy />

4.3 Configure TokenProvider

This STS endpoint configuration only supports to issue SAML tokens (2.0 or 1.1). For a full list of the supported features by the STS check this blog.

The configuration related to issuing a token is located in the following spring configuration file (cxf-transport.xml):

<bean id="transportIssueDelegate"
    <property name="tokenProviders" ref="transportTokenProviders"/>
    <property name="services" ref="transportService"/>
    <property name="stsProperties" ref="transportSTSProperties"/>
    <property name="claimsManager" ref="claimsManager"/>

<util:list id="transportTokenProviders">
    <ref bean="transportSamlTokenProvider"/>
<bean id="transportSamlTokenProvider" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider">
    <property name="attributeStatementProviders" ref="attributeStatementProvidersList" />

<util:list id="attributeStatementProvidersList">
    <ref bean="claimsAttributeProvider"/>
<bean id="claimsAttributeProvider"

The last bean claimsAttributeProvider is described in section 4.5

4.4 Configure Username/password authentication

As described in section 1. the user and passwords are managed in the file WEB-INF/passwords.xml.

To configure username/password authentication in CXF/WSS4J you must provide a CallbackHandler. The CallbackHandler is part of this example project.

The configuration is located in the following spring configuration file (cxf-transport.xml):

     <import resource="passwords.xml" />
    <bean id="upCallBackHandler"
        <property name="passwords" ref="passwords" />
    <jaxws:endpoint id="transportSTS1"
            <entry key="ws-security.callback-handler" value-ref="upCallBackHandler"/>

The bean upCallBackHandler implements the CallbackHandler which is configured as a jaxws property ws-security.callback-handler in jaxws:properties of the jaxws:endpoint configuration. 

4.5 Configure ClaimsManager

Claims data can be stored in different kind of ID systems which can be accessed using LDAP, Web Services, REST whatever. The retrieval of claims is independent of any specific security token type and group in a list of claimshandler. Each claims handler must implement what kind of claims he can provide. It's the responsibility of the ClaimsManager to call the corresponding ClaimsHandler if a specific claim is requested by a STS client.

The claims related configuration is summerized in the following spring configuration file (cxf-transport.xml):

    <import resource="userClaims.xml" />
    <bean id="claimsManager"
        <property name="claimHandlers" ref="claimHandlerList" />
    <util:list id="claimHandlerList">
        <ref bean="fileClaimsHandler"/>
    <bean id="fileClaimsHandler"
        <property name="userClaims" ref="userClaims" />
The bean userClaims is defined in the imported spring configuration file userClaims.xml.

5. Deploy the STS to Tomcat

To deploy the STS using Maven you have to follow these steps:
  • Configuring the following maven plugin    <plugin>
  • Add the server with username and password to your settings.xml
  • Ensure the user has the role "manager-script" as described here
  • Run mvn tomcat:redeploy
    (I recommend to use redeploy as deploy works the first time only)
If you use Tomcat 6, you must change the url of the tomcat maven plugin:

6. Test the STS with SoapUI

This is a sample request (called RST) to the STS:

<soap:Envelope xmlns:soap="">
      <wsse:Security soap:mustUnderstand="1" xmlns:wsse="" xmlns:wsu="">
         <wsse:UsernameToken wsu:Id="UsernameToken-1">
            <wsse:Password Type="">ecila</wsse:Password>
      <wst:RequestSecurityToken xmlns:wst="">
         <wst:Claims Dialect="" xmlns:ic="">
            <ic:ClaimType Uri=""/>
            <ic:ClaimType Uri=""/>
            <ic:ClaimType Uri=""/>
         <wsp:AppliesTo xmlns:wsp="">
            <wsa:EndpointReference xmlns:wsa="">

and this the expected response (called RSTR):

<soap:Envelope xmlns:soap="">
      <RequestSecurityTokenResponseCollection xmlns="" xmlns:ns2="" xmlns:ns3="" xmlns:ns4="" xmlns:ns5="">
               <saml2:Assertion ID="_ACF774CE2C8F387D9413183197088603" IssueInstant="2011-10-11T07:55:08.860Z" Version="2.0" xsi:type="saml2:AssertionType" xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="" xmlns:xsi="">
                  <ds:Signature xmlns:ds="">
                        <ds:CanonicalizationMethod Algorithm=""/>
                        <ds:SignatureMethod Algorithm=""/>
                        <ds:Reference URI="#_ACF774CE2C8F387D9413183197088603">
                              <ds:Transform Algorithm=""/>
                              <ds:Transform Algorithm="">
                                 <ec:InclusiveNamespaces PrefixList="xs" xmlns:ec=""/>
                           <ds:DigestMethod Algorithm=""/>
                     <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" NameQualifier="">alice</saml2:NameID>
                     <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/>
                  <saml2:Conditions NotBefore="2011-10-11T07:55:08.860Z" NotOnOrAfter="2011-10-11T08:00:08.860Z">
                     <saml2:Attribute Name="givenname" NameFormat="">
                        <saml2:AttributeValue xsi:type="xs:string">Alice</saml2:AttributeValue>
                     <saml2:Attribute Name="surname" NameFormat="">
                        <saml2:AttributeValue xsi:type="xs:string">Smith</saml2:AttributeValue>
                     <saml2:Attribute Name="emailaddress" NameFormat="">
                        <saml2:AttributeValue xsi:type="xs:string"></saml2:AttributeValue>
               <ns3:SecurityTokenReference wsse11:TokenType="" xmlns:wsse11="">
                  <ns3:KeyIdentifier ValueType="">#_ACF774CE2C8F387D9413183197088603</ns3:KeyIdentifier>
               <ns3:SecurityTokenReference wsse11:TokenType="" xmlns:wsse11="">
                  <ns3:KeyIdentifier ValueType="">_ACF774CE2C8F387D9413183197088603</ns3:KeyIdentifier>
            <wsp:AppliesTo xmlns:wsp="">
               <wsa:EndpointReference xmlns:wsa="">

Have fun!
Categories: Oliver Wulff

Using Kerberos with Web Services - part I

Colm O hEigeartaigh - Mon, 10/10/2011 - 18:00
This is the first of a two-part series on using Kerberos with Web Services, with Apache WSS4J and CXF. WSS4J 1.6.2 adds support for obtaining a Kerberos ticket from a KDC (Key Distribution Center) and converting it to a BinarySecurityToken to be inserted into the security header of a SOAP request. On the receiving side, support has been added to validate the received Kerberos ticket accordingly. CXF 2.4.2 extends the Kerberos functionality available in WSS4J 1.6.2 to add support for WS-SecurityPolicy. No support is available yet (as of CXF 2.4.2) to use a secret key to sign and encrypt message parts, this will be the subject of part II.

In this post we will talk about installing the MIT Kerberos distribution in Ubuntu, and creating the necessary credentials to run some tests. Then we will go into some system tests in CXF that show how a client can get a Kerberos AP-REQ ticket from a KDC and send it to a service provider, who then authenticates the ticket, all driven by some spring configuration and WS-SecurityPolicy.

1) Installing MIT Kerberos

1.1) Installing the product

In this section we cover how to install the MIT Kerberos distribution in Ubuntu. This is needed to run the CXF Kerberos system tests. See here for more information on using Kerberos on Ubuntu. Open a command prompt and type:
sudo apt-get install krb5-kdc krb5-admin-serverWhen the product is installing you'll be asked for the default Kerberos Version 5 realm. Enter:
WS.APACHE.ORG You will then be prompted for the hostnames of Kerberos servers in the WS.APACHE.ORG Kerberos realm. As we are installing the KDC and running the tests on the same machine, we only need to enter "localhost". Similarly, enter "localhost" when prompted for the Administrative server for the Kerberos realm.

1.2) Modifying configuration

Once apt-get has finished, we need to modify the Kerberos configuration file ("sudo vi /etc/krb5.conf"):
  • Under the "[realms]" section, add a "default_domain" entry for The entire entry should look like:
                 kdc = localhost
                 admin_server = localhost
                 default_domain =
  • Under the "[domain_realm]" section, add the following: = WS.APACHE.ORG = WS.APACHE.ORG
  • Finally, add a logging section:

        kdc = FILE:/var/log/krb5kdc.log
        admin_server = FILE:/var/log/kadmin.log
        default = FILE:/var/log/krb5lib.log 1.3) Create principals

The next step is to create some principals. Create a master key via:
sudo kdb5_util create -sThe next step is to start kadmin locally via:
sudo kadmin.localIf you run "listprincs" at the prompt you should see the ticket-granting-ticket principal "krbtgt/WS.APACHE.ORG@WS.APACHE.ORG". We will add a client principal and service principal:
addprinc alice
addprinc bob/"quit" the kadmin prompt, and start the KDC with "sudo krb5kdc". If you see no error messages then everything should be working correctly. To test this try to get a ticket for "alice" via "kinit alice", entering the password given when creating the "alice" principal.

1.4) Create keytabs

To avoid having to enter passwords when running the tests, we will create Keytabs. Start kadmin.local again ("sudo kadmin.local"), and enter:
ktadd -k /etc/alice.keytab alice
ktadd -k /etc/bob.keytab bob/ check that the keytabs were create correctly, you can inspect them with klist, e.g. "sudo klist -k /etc/alice.keytab". Finally make sure the keytabs are readable via "sudo chmod og+r /etc/*.keytab" - obviously this is not secure, but it is sufficient for this test application.

2) Running the Kerberos system tests in Apache CXF

Now that we have installed Kerberos and created the relevant principals, we can run the Kerberos system tests in Apache CXF. These tests are @Ignore'd by default. The KerberosTokenTest contains a number of different Kerberos tests. In this article we will just examine the tests that involve obtaining a Kerberos Token, and not any of the tests that involve using the secret key associated with a Kerberos Token to secure some part of the request.

Firstly, make sure that the JDK has unlimited security policies installed, and then checkout the CXF WS-Security system tests via:
svn co and comment out the "@org.junit.Ignore" entries for the first four tests, "testKerberosOverTransport", "testKerberosOverSymmetric", "testKerberosOverSymmetricSupporting" and "testKerberosOverAsymmetric". Finally, run the tests via:

        mvn test -Dtest=KerberosTokenTest

2.1) WS-SecurityPolicy configuration

The wsdl that defines the service endpoints contains WS-SecurityPolicy expressions that define the security requirements of the endpoints. The following security policies are used for the four tests defined above:
  • testKerberosOverTransport: A (one-way) transport binding is defined, with a KerberosToken required as a SupportingToken. Essentially, this means that the communication is secured with TLS, and authentication is handled by a Kerberos token.
  • testKerberosOverSymmetric: A symmetric binding is used, where a KerberosToken is required as a SignedSupportingToken. 
  • testKerberosOverSymmetricSupporting: A symmetric binding is used, where a KerberosToken is required as a SupportingToken.
  • testKerberosOverAsymmetric: An asymmetric binding is used, where a Kerberos token is required as a SignedSupportingToken.
The WS-SecurityPolicy expression used for a KerberosToken is:
<sp:KerberosToken sp:IncludeToken=".../Once">
</sp:KerberosToken>This means that a GSS V5 AP-REQ Token is required "once", in other words the initial invocation between the client and service endpoint must contain a token of this type encoded as a BinarySecurityToken in the security header of the request.

2.2) Kerberos LoginModule configuration

Both the CXF client and service endpoint use JAAS to authenticate to the KDC. The JAAS file used as part of the system test is passed to the tests via the System property "". The client (alice) uses the following login module:
alice { required 
    refreshKrb5Config=true useKeyTab=true keyTab="/etc/alice.keytab"  
};and the service endpoint (bob) uses:
bob { required
    refreshKrb5Config=true useKeyTab=true storeKey=true
    keyTab="/etc/bob.keytab" principal="bob/";
}; 2.3) Service endpoint configuration

The service endpoints are spring-loaded. Each endpoint definition contains the JAX-WS property "ws-security.bst.validator" which is defined in SecurityConstants. WSS4J uses Validator implementations to perform validation on received security tokens. This particular property means that BinarySecurityTokens are to be validated by the given reference, e.g.:
<jaxws:endpoint ...>   
        <entry key="ws-security.bst.validator" value-ref="kerberosValidator"/>
</jaxws:endpoint> "kerberosValidator" is defined as:
<bean id="kerberosValidator"
    <property name="contextName" value="bob"/>
    <property name="serviceName" value=""/>
</bean>The KerberosTokenValidator class ships with Apache WSS4J. It requires a "contextName" property, which corresponds to the JAAS context name, as well as an optional "serviceName" property. Combined with the JAAS properties file, this is all that is required for the service endpoint to validate a received Kerberos Token. 

2.4 Client configuration

Finally, the client must contact a KDC and obtain a Kerberos Token, once it sees that the service endpoint has a security policy that requires a KerberosToken. The client configuration is available here. A sample configuration for the Kerberos Test case is as follows:
<jaxws:client name="{...}DoubleItKerberosTransportPort"
           <entry key="ws-security.kerberos.client">
               <bean class="">
                   <constructor-arg ref="cxf"/>
                   <property name="contextName" value="alice"/>
                   <property name="serviceName" value=""/>
</jaxws:client>The JAX-WS property "ws-security.kerberos.client" (again, defined in SecurityConstants) corresponds to a KerberosClient object. Similar to the KerberosTokenValidator on the receiving side, this is configured with a JAAS context Name and service Name.
Categories: Colm O hEigeartaigh

Tomcat Maven Plugin now supports tomcat7

Olivier Lamy - Sun, 10/09/2011 - 14:06
After moving the Tomcat Maven Plugin from Codehaus to Apache in the Tomcat land (see previous post), I have found some time to start hacking on it.
The first feature I wanted to add was support of Apache Tomcat 7.x. So it's now implemented in trunk.
You can test it see how to configure that in your poms:

NOTE the important changes with the move to Apache and the support of Apache Tomcat 7.x:

  • You know have two "mojos": tomcat6:* and tomcat7:$

  • The groupId is now: org.apache.tomcat.maven

  • All goals are not supported: I will work on that :-)

So you can know use tomcat7 in embedded way within your Apache Maven build with: tomcat7:run.

Feel free to report any issues:

Have Fun!

Apache Maven, Maven, Apache Tomcat, Tomcat, Apache are trademarks of The Apache Software Foundation.

Categories: Olivier Lamy

Web Services Links (9 October 2011)

Glen Mazza - Sun, 10/09/2011 - 13:00

Web service related links of interest this week:


Improving decryption performance in Apache Santuario 1.5

Colm O hEigeartaigh - Fri, 10/07/2011 - 13:10
Andreas Veithen alerted me some months back to a performance problem in Apache Santuario when decrypting messages. The issue emerged when some profiling was done on Dennis Sosnoski's test-code for measuring WS-Security performance across different web services stacks (see the original article here).

The test scenario involves deploying an Apache CXF 2.4.2 endpoint in Tomcat and repeatedly testing the "signencr" invocation defined in the article (WS-Security signing of body and headers, with timestamp and encryption of body) using a CXF client. Two types of test-runs were executed, 1000 "large" messages at 0.2 density in one run, and 10000 "small" messages at 0.05 density in another. When doing some profiling using a sampling profiler on the client, it emerged that the time it took to deserialize a decrypted XML String into a DOM element was taking around 20% of the total execution time for all WS-Security processing!

The way the default deserializing algorithm works in Apache Santuario 1.4.x is to parse the decrypted XML String into a new Document object, which is then imported into the existing Document. As Apache Xerces defers the creation of Node objects, the import operation triggers the full expansion of the DOM tree.

There are a number of alternatives to using the DocumentBuilder/importNode approach used in Santuario 1.4.x. The first approach is to use a Transformer object to transform the Source (XML String) into a placeholder Node belonging to the existing Document. This approach avoids having to explicitly import the nodes back to the existing Document. The second approach, is to use the streaming API available in the JDK 1.6 (not an option for Santuario 1.5 which must compile against the JDK 1.5).

Here are some (ad-hoc) test results. The first results show the total time for each test-run using both algorithms:
  • Large Messages:
    • Document Serializer: 119.46s
    • Transform Serializer: 115.68s
  • Small Messages:
    • Document Serializer: 222.32s
    • Transform Serializer: 216.76s
The next results show the time spent in the Serializer.deserialize() operation as a percentage of the total WS-Security processing time:
  • Large Messages:
    • Document Serializer: 19.92%
    • Transform Serializer: 18.04%
  • Small Messages:
    • Document Serializer: 24.54%
    • Transform Serializer: 18.36%
As there is a clear performance improvement in using the Transformer approach, it makes sense to use this as the default serializing mechanism in Apache Santuario 1.5. The Serializer interface is now public, and a different implementation can be set on XMLCipher. Two implementations are provided in the code, DocumentSerializer and TransformSerializer (the new default algorithm). If anyone is interested in running experiments of their own, the StreamSerializer algorithm is available here.

Do you have any suggestions on how this could be improved further? Clearly, the time it takes to deserialize a decrypted XML String into a DOM node still takes far longer than it should. A fully StAX approach for XML Security would surely offer much improved performance - this is under development and planned for next year.
Categories: Colm O hEigeartaigh

New Camel Webinar Series in german language

Christian Schneider - Wed, 10/05/2011 - 10:30

Blog post added by Christian Schneider

Bernhard Schuhmann and I will be holding a new free Camel Webinar series in german starting in about a week at Oct 12th. More information and signup at The webinars are based on Hadrian Zbarcea´s english webinar series and will be similar in scope. We will start with an introduction in the first part where you learn to write and deploy your first camel route. In part 2 we focus on the integration patterns. In the last part we will then dive into more advanced camel features.

View Online | Add Comment
Categories: Christian Schneider

Speaking at the W-JAX conference in Munich and at the SOA BPM days in Düsseldorf

Christian Schneider - Tue, 10/04/2011 - 15:35

Blog post edited by Christian Schneider

The W-JAX in Munich is one of the most important Java conferences in germany. Speakers include well known experts like Dr Gernot Starke, Jürgen Höller and Adam Bien. On the 10th of November there will be a special day around the Apache integration projects. I will do the session about Apache Camel ("Integration ganz einfach mit Apache Camel"). Some colleagues from talend will hold talks about Apache Karaf and Apache CXF. I am looking forward to meeting people from the community and also people new to Apache Camel.

In mid October there is another chance to learn about Camel. During the SOA, BPM and Integration days in Düsseldorf I will do a 2 hour talk and live demo around Apache Camel on Thursday the 13th of October. The conference is much smaller than W-JAX so there will be plenty of time for discussions.

View Online | Add Comment
Categories: Christian Schneider

Apache WSS4J 1.6.3 released

Colm O hEigeartaigh - Tue, 10/04/2011 - 14:39
Apache WSS4J 1.6.3 has been released. It can be downloaded here and the issues fixed are listed in the WSS4J JIRA.

Probably the most significant part of this release is that WSS4J now fully supports the Kerberos Token Profile 1.1. In the previous release, support was added to retrieve a Kerberos token from a KDC, and insert it into the security header of a request, and then validate it accordingly on the receiving side. In WSS4J 1.6.3, support has been added to use the secret key associated with the Kerberos token to sign and encrypt the request, and to verify and decrypt on the receiving side. I am planning on writing a series of blog posts soon about how to use Kerberos with WSS4J and CXF. The forthcoming Apache CXF 2.4.3 release will have full WS-SecurityPolicy support for working with Kerberos, based on the work done in WSS4J 1.6.3.

In addition to the Kerberos work, WSS4J 1.6.3 features an upgraded Opensaml dependency, as well as several bug fixes.
Categories: Colm O hEigeartaigh

Deploying and Using a CXF Security Token Service (STS)

Glen Mazza - Tue, 10/04/2011 - 13:00

Thanks to Talend colleague Colm O hEigeartaigh's excellent work, the upcoming CXF 2.5.x will feature its own Security Token Service (STS). In this tutorial, I'll be showing how a CXF web service client (WSC) can obtain a SAML security token from the CXF STS and make calls using that token to a CXF web service provider (WSP). This blog entry is much the same as the earlier Metro STS tutorial, except I'll be using X.509 authentication of the WSC by the STS instead of UsernameToken authentication. Using an STS shifts the validation of the client from the web service provider to the STS, meaning that the web service provider would not need to be individually configured to trust each client accessing it. Trust relationships are therefore needed only between the WSC and the STS, and between the WSP and the STS. (See the links at the bottom of the Metro STS tutorial for more information on STSs.)

As usual, we'll rely on the sample DoubleIt web service provider and client as the starting basis for our work. The source code for a closely similar example (jaxws-cxf-sts) will be available in the upcoming open source Talend Service Factory 2.5 and Talend ESB 5.0; in the meantime, a pre-release version can be pulled off GitHub. Note the information within this tutorial is quite new, provided "as is" and may have errors within it, so be sure to carefully check and test all work before moving to production with any of this information. Also of course, be sure not to use any of the sample keys or passwords here in production use.

Steps involved for hosting a CXF-based STS on Tomcat:

  1. Run the DoubleIt web service and SOAP client. First, update the cxf.version in the DoubleIt/pom.xml file to 2.5.0-SNAPSHOT (or 2.5.0 after official release of 2.5). Then follow the DoubleIt tutorial and run the CXF version of the WSP and WSC. Confirm that SOAP calls between the WSC and WSP are working before proceeding.

  2. Create keystores for the client, service, and STS. Follow Step #3 of the Metro STS tutorial for this step, with one addition at the very end: Since we're using X.509 authentication between WSC and STS here (unlike UsernameToken with the Metro STS tutorial), the former's public key will need to be added to the latter's truststore as follows:

    keytool -keystore stsstore.jks -storepass stsspass -import -noprompt -trustcacerts -alias myclientkey -file client.cer
  3. Add an STS submodule to DoubleIt. This will hold our CXF-based STS, deployable as a separate WAR to Tomcat. Steps:

    1. In the DoubleIt folder, create a sts-war directory alongside the currently existing service, war, and client folders. Add the following folders underneath sts-war: for Linux: mkdir -p sts-war/src/main/java/sts mkdir -p sts-war/src/main/resources mkdir -p sts-war/src/main/webapp/WEB-INF/wsdl mkdir -p sts-war/src/main/webapp/WEB-INF/lib for Windows: mkdir sts-war\src\main\java\sts mkdir sts-war\src\main\resources mkdir sts-war\src\main\webapp\WEB-INF\wsdl mkdir sts-war\src\main\webapp\WEB-INF\lib
    2. Add the following pom.xml file to the sts-war directory.
    3. <project xmlns="" xmlns:xsi="" xsi:schemaLocation=""> <modelVersion>4.0.0</modelVersion> <parent> <groupId></groupId> <artifactId>basic-doubleit</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>sts-war</artifactId> <name>CXF STS</name> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-services-sts-core</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.6.1</version> <scope>runtime</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>tomcat-maven-plugin</artifactId> <version>1.1</version> <configuration> <server>myTomcat</server> <url>http://localhost:8080/manager/text</url> <path>/${}</path> </configuration> </plugin> </plugins> <!-- Name of the generated WAR file --> <finalName>DoubleItSTS</finalName> </build> </project>
    4. To the parent DoubleIt/pom.xml file, you'll need to add the new submodule to the module list:

      <modules> <module>service</module> <module>war</module> <module>client</module> <module>sts-war</module> </modules> well as both WS-Policy dependencies listed in Step #2 of the UsernameToken with CXF tutorial.

    5. In the STS' src/main/resources folder, place the stsstore.jks file you created in Step #2 along with the following configuration file:
  4. Create the STS WSDL and configure the STS' security information. NetBeans is a useful tool for creating STS WSDLs that can be used out-of-the-box with the Metro STS. They are mostly workable as-is for a CXF STS, although Metro-specific security configuration declarations (such as keystore and truststore locations and passwords) in the WSDL need to be removed as they are declared in a separate cxf-servlet.xml file in CXF. Another alternative is to start with the base WS-Trust 1.4 WSDL and expand it based on the WSC-to-STS authentication rules (e.g., UsernameToken or X.509) you wish to require--the CXF user's list and the OASIS WS-SecurityPolicy Examples guide can help in formulating the necessary policy statements.

    As mentioned earlier we'll be using X.509 authentication (keystore/truststore) as the WSC-to-STS configuration method. Place the following DoubleItSTSService.wsdl file which declares this requirement in the sts-war/src/main/webapp/WEB-INF/wsdl folder:


    <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="" xmlns:tns="" xmlns:wstrust="" xmlns:wsdl="" xmlns:soap="" xmlns:wsap10="" xmlns:wsu="" xmlns:wsp="" xmlns:wst="" xmlns:xs="" xmlns:wsam=""> > <wsdl:types> <xs:schema elementFormDefault="qualified" targetNamespace=''> <xs:element name='RequestSecurityToken' type='wst:AbstractRequestSecurityTokenType' /> <xs:element name='RequestSecurityTokenResponse' type='wst:AbstractRequestSecurityTokenType' /> <xs:complexType name='AbstractRequestSecurityTokenType'> <xs:sequence> <xs:any namespace='##any' processContents='lax' minOccurs='0' maxOccurs='unbounded' /> </xs:sequence> <xs:attribute name='Context' type='xs:anyURI' use='optional' /> <xs:anyAttribute namespace='##other' processContents='lax' /> </xs:complexType> <xs:element name='RequestSecurityTokenCollection' type='wst:RequestSecurityTokenCollectionType' /> <xs:complexType name='RequestSecurityTokenCollectionType'> <xs:sequence> <xs:element name='RequestSecurityToken' type='wst:AbstractRequestSecurityTokenType' minOccurs='2' maxOccurs='unbounded' /> </xs:sequence> </xs:complexType> <xs:element name='RequestSecurityTokenResponseCollection' type='wst:RequestSecurityTokenResponseCollectionType' /> <xs:complexType name='RequestSecurityTokenResponseCollectionType'> <xs:sequence> <xs:element ref='wst:RequestSecurityTokenResponse' minOccurs='1' maxOccurs='unbounded' /> </xs:sequence> <xs:anyAttribute namespace='##other' processContents='lax' /> </xs:complexType> </xs:schema> </wsdl:types> <!-- WS-Trust defines the following GEDs --> <wsdl:message name="RequestSecurityTokenMsg"> <wsdl:part name="request" element="wst:RequestSecurityToken" /> </wsdl:message> <wsdl:message name="RequestSecurityTokenResponseMsg"> <wsdl:part name="response" element="wst:RequestSecurityTokenResponse" /> </wsdl:message> <wsdl:message name="RequestSecurityTokenCollectionMsg"> <wsdl:part name="requestCollection" element="wst:RequestSecurityTokenCollection" /> </wsdl:message> <wsdl:message name="RequestSecurityTokenResponseCollectionMsg"> <wsdl:part name="responseCollection" element="wst:RequestSecurityTokenResponseCollection" /> </wsdl:message> <!-- This portType is an example of an STS supporting full protocol --> <wsdl:portType name="STS"> <wsdl:operation name="Cancel"> <wsdl:input wsam:Action="" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="Issue"> <wsdl:input wsam:Action="" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="" message="tns:RequestSecurityTokenResponseCollectionMsg" /> </wsdl:operation> <wsdl:operation name="Renew"> <wsdl:input wsam:Action="" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="Validate"> <wsdl:input wsam:Action="" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="KeyExchangeToken"> <wsdl:input wsam:Action="" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="RequestCollection"> <wsdl:input message="tns:RequestSecurityTokenCollectionMsg" /> <wsdl:output message="tns:RequestSecurityTokenResponseCollectionMsg" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="X509_Binding" type="wstrust:STS"> <wsp:PolicyReference URI="#X509_policy" /> <soap:binding style="document" transport="" /> <wsdl:operation name="Issue"> <soap:operation soapAction="" /> <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"> <soap:operation soapAction="" /> <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="Cancel"> <soap:operation soapAction="" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="Renew"> <soap:operation soapAction="" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="KeyExchangeToken"> <soap:operation soapAction="" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="RequestCollection"> <soap:operation soapAction="" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsp:Policy wsu:Id="X509_policy"> <wsp:ExactlyOne> <wsp:All> <wsap10:UsingAddressing /> <sp:AsymmetricBinding xmlns:sp=""> <wsp:Policy> <sp:InitiatorToken> <wsp:Policy> <sp:X509Token sp:IncludeToken=""> <wsp:Policy> <sp:WssX509V3Token10 /> </wsp:Policy> </sp:X509Token> </wsp:Policy> </sp:InitiatorToken> <sp:RecipientToken> <wsp:Policy> <sp:X509Token sp:IncludeToken=""> <wsp:Policy> <sp:WssX509V3Token10 /> <sp:RequireIssuerSerialReference /> </wsp:Policy> </sp:X509Token> </wsp:Policy> </sp:RecipientToken> <sp:AlgorithmSuite> <wsp:Policy> <sp:TripleDesRsa15 /> </wsp:Policy> </sp:AlgorithmSuite> <sp:Layout> <wsp:Policy> <sp:Lax /> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp /> <sp:EncryptSignature /> <sp:OnlySignEntireHeadersAndBody /> </wsp:Policy> </sp:AsymmetricBinding> <sp:Wss11 xmlns:sp=""> <wsp:Policy> <sp:MustSupportRefKeyIdentifier /> <sp:MustSupportRefIssuerSerial /> <sp:MustSupportRefThumbprint /> <sp:MustSupportRefEncryptedKey /> </wsp:Policy> </sp:Wss11> <sp:Trust13 xmlns:sp=""> <wsp:Policy> <sp:MustSupportIssuedTokens /> <sp:RequireClientEntropy /> <sp:RequireServerEntropy /> </wsp:Policy> </sp:Trust13> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="Input_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts xmlns:sp=""> <sp:Body /> <sp:Header Name="To" Namespace="" /> <sp:Header Name="From" Namespace="" /> <sp:Header Name="FaultTo" Namespace="" /> <sp:Header Name="ReplyTo" Namespace="" /> <sp:Header Name="MessageID" Namespace="" /> <sp:Header Name="RelatesTo" Namespace="" /> <sp:Header Name="Action" Namespace="" /> </sp:SignedParts> <sp:EncryptedParts xmlns:sp=""> <sp:Body /> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="Output_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts xmlns:sp=""> <sp:Body /> <sp:Header Name="To" Namespace="" /> <sp:Header Name="From" Namespace="" /> <sp:Header Name="FaultTo" Namespace="" /> <sp:Header Name="ReplyTo" Namespace="" /> <sp:Header Name="MessageID" Namespace="" /> <sp:Header Name="RelatesTo" Namespace="" /> <sp:Header Name="Action" Namespace="" /> </sp:SignedParts> <sp:EncryptedParts xmlns:sp=""> <sp:Body /> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsdl:service name="SecurityTokenService"> <wsdl:port name="X509_Port" binding="tns:X509_Binding"> <soap:address location="dummy_address" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
  5. Note the soap:address given in the wsdl:service section above is not important, as the CXF runtime will overwrite it based on other deployment information as explained in Note #2 of my WSDL-first tutorial. Next we'll need to provide the necessary configuration information for the above WSDL. Place the following cxf-servlet.xml file in the sts-war/src/main/resources folder:


    <beans xmlns="" xmlns:cxf="" xmlns:jaxws="" xmlns:test="" xmlns:xsi="" xmlns:util="" xsi:schemaLocation=""> <import resource="classpath:META-INF/cxf/cxf.xml"/> <cxf:bus> <cxf:features> <cxf:logging /> </cxf:features> </cxf:bus> <bean id="x509STSProviderBean" class=""> <property name="issueOperation" ref="x509IssueDelegate" /> <property name="validateOperation" ref="x509ValidateDelegate" /> </bean> <bean id="x509IssueDelegate" class="org.apache.cxf.sts.operation.TokenIssueOperation"> <property name="tokenProviders" ref="x509SamlTokenProvider" /> <property name="services" ref="x509Service" /> <property name="stsProperties" ref="x509STSProperties" /> </bean> <bean id="x509ValidateDelegate" class="org.apache.cxf.sts.operation.TokenValidateOperation"> <property name="tokenValidators" ref="x509SamlTokenValidator" /> <property name="stsProperties" ref="x509STSProperties" /> </bean> <bean id="x509SamlTokenProvider" class="org.apache.cxf.sts.token.provider.SAMLTokenProvider"/> <bean id="x509SamlTokenValidator" class="org.apache.cxf.sts.token.validator.SAMLTokenValidator"/> <bean id="x509Service" class="org.apache.cxf.sts.service.StaticService"> <property name="endpoints" ref="x509Endpoints" /> </bean> <util:list id="x509Endpoints"> <value>http://localhost:8080/doubleit/services/doubleit.*</value> </util:list> <bean id="x509STSProperties" class="org.apache.cxf.sts.StaticSTSProperties"> <property name="signaturePropertiesFile" value="" /> <property name="signatureUsername" value="mystskey" /> <property name="callbackHandlerClass" value="sts.PasswordCallbackHandler" /> <property name="encryptionPropertiesFile" value="" /> <property name="issuer" value="DoubleItSTSIssuer" /> <property name="encryptionUsername" value="myservicekey" /> </bean> <jaxws:endpoint id="X509STS" implementor="#x509STSProviderBean" address="/X509" wsdlLocation="/WEB-INF/wsdl/DoubleItSTSService.wsdl" xmlns:ns1="" serviceName="ns1:SecurityTokenService" endpointName="ns1:X509_Port"> <jaxws:properties> <entry key="ws-security.callback-handler" value="sts.PasswordCallbackHandler" /> <entry key="" value="" /> <entry key="ws-security.signature.username" value="mystskey" /> <entry key="ws-security.encryption.username" value="useReqSigCert" /> </jaxws:properties> </jaxws:endpoint> </beans>

    We'll also of course need a web.xml for the STS war. Since we're using message-layer X.509 encryption we can go without configuring the STS for SSL, but you'll want that step if you're using UsernameToken authentication of the WSC to the STS. Place the following file in the sts-war/src/main/webapp/WEB-INF folder:


    <web-app version="2.4" xmlns="" xmlns:xsi="" xsi:schemaLocation=""> <display-name>CXF STS</display-name> <servlet> <servlet-name>sts</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <init-param> <param-name>config-location</param-name> <param-value>WEB-INF/cxf-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>sts</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> </web-app>

    At this stage, it would be good to test that the STS can be deployed. Run mvn clean install from the DoubleIt root folder, then mvn tomcat:redeploy -pl sts-war to deploy the web service on Tomcat (if you haven't already, see the WSDL-first tutorial to see how to configure Maven to deploy on Tomcat.) Make sure you can view the WSDL list at http://localhost:8080/DoubleItSTS as well as the WSDL itself (linked from that page) before proceeding.

  6. Configure the web service provider to require the SAML tokens provided by the STS. Follow Step #3 of the CXF w/Metro STS tutorial for this step, except use the following updated WSDL for the WSP:

    DoubleIt.wsdl (with policy requirements added): <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="DoubleIt" xmlns:xsd="" xmlns:wsdl="" xmlns:soap="" xmlns:di="" xmlns:tns="" xmlns:wsp="" xmlns:wsu="" xmlns:wsam="" xmlns:sp="" xmlns:t="" xmlns:wsaw="" xmlns:wsx="" targetNamespace="" > <wsdl:types> <xsd:schema targetNamespace=""> <xsd:element name="DoubleIt"> <xsd:complexType> <xsd:sequence> <xsd:element name="numberToDouble" type="xsd:int"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="DoubleItResponse"> <xsd:complexType> <xsd:sequence> <xsd:element name="doubledNumber" type="xsd:int" /> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> </wsdl:types> <wsdl:message name="DoubleItRequest"> <wsdl:part element="di:DoubleIt" name="parameters" /> </wsdl:message> <wsdl:message name="DoubleItResponse"> <wsdl:part element="di:DoubleItResponse" name="parameters" /> </wsdl:message> <wsdl:portType name="DoubleItPortType"> <wsdl:operation name="DoubleIt"> <wsdl:input message="tns:DoubleItRequest" /> <wsdl:output message="tns:DoubleItResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="DoubleItBinding" type="tns:DoubleItPortType"> <wsp:PolicyReference URI="#DoubleItBindingPolicy"/> <soap:binding style="document" transport="" /> <wsdl:operation name="DoubleIt"> <soap:operation soapAction=""/> <wsdl:input><soap:body use="literal"/> <wsp:PolicyReference URI="#DoubleItBinding_DoubleIt_Input_Policy"/> </wsdl:input> <wsdl:output><soap:body use="literal"/> <wsp:PolicyReference URI="#DoubleItBinding_DoubleIt_Output_Policy"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="DoubleItService"> <wsdl:port name="DoubleItPort" binding="tns:DoubleItBinding"> <soap:address location="http://localhost:8080/doubleit/services/doubleit"/> </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <wsam:Addressing wsp:Optional="false"> <wsp:Policy/> </wsam:Addressing> <sp:SymmetricBinding> <wsp:Policy> <sp:ProtectionToken> <wsp:Policy> <sp:IssuedToken sp:IncludeToken=""> <sp:RequestSecurityTokenTemplate> <t:TokenType></t:TokenType> <t:KeyType></t:KeyType> <t:KeySize>256</t:KeySize> </sp:RequestSecurityTokenTemplate> <wsp:Policy> <sp:RequireInternalReference/> </wsp:Policy> <sp:Issuer> <wsaw:Address>http://localhost:8080/DoubleItSTS/DoubleItSTSServiceUT</wsaw:Address> <wsaw:Metadata> <wsx:Metadata> <wsx:MetadataSection> <wsx:MetadataReference> <wsaw:Address>http://localhost:8080/DoubleItSTS/DoubleItSTSServiceUT/mex</wsaw:Address> </wsx:MetadataReference> </wsx:MetadataSection> </wsx:Metadata> </wsaw:Metadata> </sp:Issuer> </sp:IssuedToken> </wsp:Policy> </sp:ProtectionToken> <sp:Layout> <wsp:Policy> <sp:Lax/> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp/> <sp:OnlySignEntireHeadersAndBody/> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic256/> </wsp:Policy> </sp:AlgorithmSuite> </wsp:Policy> </sp:SymmetricBinding> <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> <wsp:Policy wsu:Id="DoubleItBinding_DoubleIt_Input_Policy"> <wsp:ExactlyOne> <wsp:All> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace=""/> <sp:Header Name="From" Namespace=""/> <sp:Header Name="FaultTo" Namespace=""/> <sp:Header Name="ReplyTo" Namespace=""/> <sp:Header Name="MessageID" Namespace=""/> <sp:Header Name="RelatesTo" Namespace=""/> <sp:Header Name="Action" Namespace=""/> <sp:Header Name="AckRequested" Namespace=""/> <sp:Header Name="SequenceAcknowledgement" Namespace=""/> <sp:Header Name="Sequence" Namespace=""/> <sp:Header Name="CreateSequence" Namespace=""/> <!--CXF uses by default for the docs/200702 ones: Namespace=""/--> </sp:SignedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="DoubleItBinding_DoubleIt_Output_Policy"> <wsp:ExactlyOne> <wsp:All> <sp:EncryptedParts> <sp:Body/> </sp:EncryptedParts> <sp:SignedParts> <sp:Body/> <sp:Header Name="To" Namespace=""/> <sp:Header Name="From" Namespace=""/> <sp:Header Name="FaultTo" Namespace=""/> <sp:Header Name="ReplyTo" Namespace=""/> <sp:Header Name="MessageID" Namespace=""/> <sp:Header Name="RelatesTo" Namespace=""/> <sp:Header Name="Action" Namespace=""/> <sp:Header Name="AckRequested" Namespace=""/> <sp:Header Name="SequenceAcknowledgement" Namespace=""/> <sp:Header Name="Sequence" Namespace=""/> <sp:Header Name="CreateSequence" Namespace=""/> </sp:SignedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </wsdl:definitions>
  7. Configure the SOAP client to use the STS to obtain the security token. Steps:

    • In the client package, create the following password callback handler, used to obtain the keystore password necessary for obtaining the client's public key:

      package client; import; import; import; import; import; 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) { // CXF WSPasswordCallback pc = (WSPasswordCallback) callbacks[i]; if ("myclientkey".equals(pc.getIdentifier())) { pc.setPassword("ckpass"); break; } } } } }
    • In the client submodule's resources folder, create the following file:
    • Move the clientstore.jks keystore to the client submodule's resources folder.

    • Also in the resources folder, the following cxf.xml file needs to be created. It provides the necessary security configuration information for the WSC's communication with the STS.


      <beans xmlns="" xmlns:xsi="" xmlns:jaxws="" xmlns:cxf="" xsi:schemaLocation=""> <jaxws:client name="{}DoubleItPort" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.sts.client"> <bean class=""> <constructor-arg ref="cxf"/> <property name="wsdlLocation" value="DoubleItSTSService.wsdl"/> <property name="serviceName" value="{}DoubleItSTSService"/> <property name="endpointName" value="{}DoubleItSTSPort"/> <property name="properties"> <map> <entry key="ws-security.signature.username" value="myclientkey"/> <entry key="ws-security.callback-handler" value="client.ClientCallbackHandler"/> <entry key="" value=""/> <entry key="" value=""/> <entry key="ws-security.encryption.username" value="mystskey"/> </map> </property> </bean> </entry> </jaxws:properties> </jaxws:client> </beans>
    • Copy the DoubleItSTSService.wsdl from the service's resources folder to the client's resources folder, as it is referenced by the above cxf.xml configuration file.

  8. Run the client and test under error situations to make sure authentication is working properly. Run the client as shown in Step #10 of the WSDL-first tutorial and make sure you see the same output.

    If the client is making SOAP calls successfully, it would probably be good to run the calls with Wireshark to see the SOAP requests and responses returned. Make sure that you can see that the contents within the soap envelope are being encrypted between WSC and STS and between WSC and WSP. Finally, testing the client again under various invalid circumstances (wrong callback handler passwords, no trust relationship between STS and service or STS and client, no SOAP header sent to service, etc.) can help confirm the STS and WSP are working in accordance with their WS-SecurityPolicy declarations.

    If the client is not returning the expected SOAP response, a good first check would be to make sure the STS and Service WSDLs are visible from a browser as discussed at the end of Steps #4 and #5 above. If you can view both WSDLs then checking the CXF error messages returned in the Tomcat error logs and using Wireshark can help pinpoint the problem. To speed up iterative debugging, note that the mvn clean install tomcat:redeploy command, if run from the DoubleIt root folder, will deploy and undeploy both the STS (sts-war) and the web service provider (war) within a single step.


New default http(s) transport layer in maven core 3.x

Olivier Lamy - Mon, 10/03/2011 - 10:29
In the current maven core dev trunk, we have recently replace the http(s) transport layer from lightweight wagon (based on default jdk http(s) mechanism) to the wagon http module based on Apache httpclient [1].

See related post.

This change include two improvements:
* connection pool mechanism (to avoid http(s) connection recreation for each artifacts download).
* preemptive authz mechanism which will prevent uploading artifacts twice.

As it's important change in the core distribution, we like to have some feedbacks from users a SNAPSHOT distribution (based on rev 1178324) is available here :

mvn -v display: Apache Maven 3.0.4-SNAPSHOT (r1178324; 2011-10-03 10:07:26+0200)

An other way to test it with maven3 is to download the shaded jar [2] and copy it in $M2_HOME/lib/ext.

Feel free to test it and report any issues you will have with this new default http(s) transport layer.

Thanks in advance for your testing time and have fun !


Categories: Olivier Lamy

Describing JSON Services in WADL

Sergey Beryozkin - Sun, 10/02/2011 - 17:53
WADL can describe RESTful XML services really well, by having request and response representations linked to corresponding XML or Relax NG schema element declarations.
However, you've most likely seen the following fragments showing that both XML and JSON representations are supported:



The above fragment can describe a method like this one:

public Book getBook() {...}

So given the WADL fragment above, the consumer can get an idea of how an XML response will look like, and thus how to consume and possibly validate it. The description of the JSON response representation gives no information at all.

That is not fair I can hear you, JSON fans, saying :-). Or perhaps I can hear people saying WADL is not good enough for describing JSON services. But CXF makes things possible :-), and hopefully the following two recent updates can help:

1. Setting a linkJsonToXmlSchema property on CXF WADLGenerator will result in a fragment like this one be created:



Well, describing JSON representation with XML schema is not technically correct, but more often than not an XML schema element instance will give a pretty good idea how a JSON will look like, for example, a Book bean can be used to generate both XML and JSON sequences by the providers in charge.

2. Setting HTTP Accept header to application/json when requesting WADL will result in a WADL JSON representation returned. For example, given


will return a JSON-format WADL instance. Is that really cool ? You bet it is. What about WADL grammar referencing XML schemas, does it really make sense to JSON-format XML schemas ? No it does not, but we have a JSON schema initiative so what you need to do is just configure WADLGenerator to reference a schema like the one describing Products in this section and here you go. For example:

WADLGenerator wg = new WADLGenerator();
// do not create JAXB context
// let JSON provider handle it

The provider can have the above properties set from Spring if needed.
The reference to the json.schema will be replaced with an absolute URI so the consumer handling a WADL JSON representation will be able to GET the referenced schema in the follow-up request.

For the above approach to become of some practical use, the tooling support is important. Consider opening a JIRA in the SoapUI project, vote for it and see what happens :-).

Enjoy !
Categories: Sergey Beryozkin

This Week's Links (2 October 2011)

Glen Mazza - Sun, 10/02/2011 - 13:00

Web service related links of interest this week:

Karaf Links:


Apache Maven Wagon 2.0 released

Olivier Lamy - Thu, 09/29/2011 - 21:57
Apache Maven Wagon 2.0 has been released with some nice fixes/features.
See full changelog

The most important features are :
* using http(s) connection pooling: see my previous post.
* support of preemptive authentication: yes this will prevent your artifacts to be uploaded twice (as it was done until this release)

You can test that now. Download the shaded jar: wagon-http-2.0-shaded.jar and put it in your $M2_HOME/lib/ext (for maven 3+)

Note this version will part of Apache Maven official distribution in the next 3.0.4 release.

Have Fun !

Apache Maven, Maven, Apache are trademarks of The Apache Software Foundation.

Categories: Olivier Lamy

Adding X.509 security headers to Apache CXF SOAP calls (WS-SecurityPolicy method)

Glen Mazza - Tue, 09/27/2011 - 13:00

This blog entry shows the modifications needed for the WSS4J interceptor-based CXF X509 token profile tutorial to use WS-SecurityPolicy instead. This method, as earlier shown for Metro and for CXF with the UsernameToken profile, is for when you wish to declare security requirements as WS-Policy elements within the WSDL instead of explicitly configuring interceptors.

The finished source code for this version (minus the keystores, which can be quickly created as shown in the original tutorial) is available here.

Just the following changes are needed from the original tutorial:

  • For Step #1, also add the cxf-rt-ws-policy dependency listed in Step #2 of the CXF/UsernameToken tutorial.

  • For Step #3, Substep #1, instead of having a client-context.xml file, use the following cxf.xml configuration file (important: note the filename change!), and place it in the same resources directory. Among other changes, this new file omits the explicit WSS4J interceptor declarations from the original version.

    <beans xmlns="" xmlns:xsi="" xmlns:jaxws="" xsi:schemaLocation=""> <jaxws:client name="{}DoubleItPort" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.callback-handler" value="client.ClientKeystorePasswordCallback"/> <entry key="" value=""/> <entry key="" value=""/> <entry key="ws-security.encryption.username" value="myservicekey"/> </jaxws:properties> </jaxws:client> </beans>

    Skip substep #3--the file from the original DoubleIt tutorial should be used. (However, you may wish to add the logging interceptors as given in this substep to see the SOAP requests and responses at the console window.)

  • For the service provider configuration in Step #4, replace the DoubleIt.wsdl in the service project with the WS-Policy-enhanced WSDL found in Step #2 of the Metro/X509 tutorial (give it the same name). After so doing, remove its <sc:keystore/> and <sc:truststore/> elements as those are Metro-specific.

    Next, in the war subproject's web.xml file's contextConfigLocation parameter, add the two additional modules shown in Step #5 of the CXF/UsernameToken tutorial.

    Finally, use the below cxf-servlet.xml file instead of the one given in the original tutorial. It removes the service-side WSS4J interceptor declarations while retaining keystore/truststore configuration information.

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="" xmlns:xsi="" xmlns:jaxws="" xmlns:soap="" xsi:schemaLocation=""> <bean id="myPasswordCallback" class="service.ServiceKeystorePasswordCallback" /> <jaxws:endpoint id="doubleit" implementor="service.DoubleItPortTypeImpl" address="/doubleit" wsdlLocation="WEB-INF/wsdl/DoubleIt.wsdl"> <jaxws:properties> <entry key="ws-security.callback-handler"> <ref bean="myPasswordCallback"/> </entry> <entry key="" value=""/> <entry key="" value=""/> <entry key="ws-security.encryption.username" value="useReqSigCert"/> </jaxws:properties> </jaxws:endpoint> </beans>

Enterprise level services coming to Apache CXF

Daniel Kulp - Mon, 09/26/2011 - 23:07
This past week, there was a discussion on the Apache CXF developer list about adding an enterprise grade Security Token Service (STS) into CXF. Talend has been developing an STS internally for some of our customers for a while now and we’re pretty excited to be able to contribute the results of that work back [...]
Categories: Daniel Kulp

Karaf Tutorial Part 3 - Improving configuration editing using the OSGI Metatype Service and the Felix Webconsole

Christian Schneider - Mon, 09/26/2011 - 18:47

Blog post added by Christian Schneider

In Karaf Tutorial Part 2 - Using the Configuration Admin Service we learned how to configure our bundles using simple configurations.

In this part we will learn how to use the Metatype Service and the Felix Webconsole to easily create and edit these configurations

Using the Webconsole to edit an untyped Configuration

So when we have the Karaf container from Part 2 running and the config present we can already use the Felix Webconsole to edit the configuration.

> features:install webconsole

Open your browser with http://localhost:8181/system/console/configMgr

You will see the list of configurations the config admin service knows about:

Untyped Configuration

So the first thing we want to see is the untyped configuration. To see this copy the ConfigApp.cfg file from the git sources to the etc dir of Karaf. It should now be listed in the above list. If you click edit you will see the following:

So you get a freeform text editor with the current config. You can edit and save the config.The config is changed in the config admin service and internally persisted but not written to the etc dir (in current Karaf version).

Now delete the file from etc again. The config will not be shown in the list anymore.

Typed configuration

Now we will take a look at typed configuration. The Felix Webconsole can create typed configurations and also show a nice Editor for them.

To enable this we need to create OSGi Metatype information in our bundle. To do this simply create a file in the directory OSGI-INF/metatype.

For our configapp example the following config will work:

<?xml version="1.0" encoding="UTF-8"?> <MetaData xmlns=""      xmlns:xsi=""      xsi:schemaLocation="      ">      <OCD description="Configured Example Application" name="ConfigApp" id="ConfigApp">          <AD name="Title" id="title" required="true" type="String" default="Default Title" description="Title for the Application"/>      </OCD>      <Designate pid="ConfigApp">          <Object ocdref="ConfigApp"/>      </Designate> </MetaData>

So this is just an xml file with the MetaType Namespace. The object class definition (OCD) Element represents a configuration.

Id to reference in the designate element
User friendly name for editors
Longer description for editors

The  attribute definition (AD) represents an attribute.

ID for programmatic retrieval of this attribute
User friendly name to show in editors
Longer description for editors
(true|no) Determines if this attribute has to be filled
(String | Long | Double | Float | Integer | Byte |Char |Boolean | Short)
Default value if the attribute is not yet present

You can also define the values to choose from.

See for more information about the OSGi MetaType Service.

The last thing to define is the Designate element which maps the object class defintion to a config admin pid.

Test the Typed Config

Now build the configapp project using mvn install and copy the configapp.jar to the deploy directory of Karaf. The Webconsole should now show the ConfigApp Element in the configurations tab even if no such config exists.

You can then click edit and should see the following screen:

So we get a nice form to edit our configuration and also get default values if we create a new config. A click on Save will create or update this config in the config admin service and out bundle will reflect the change.

To see a larger example you can edit the configuration of the felix fileinstall bundle which will show the following screen:


So we have learned how to edit typed and untyped configuration with the Felix Webconsole and how to define configuration metadata.

View Online | Add Comment
Categories: Christian Schneider

Karaf Tutorial Part 2 - Using the Configuration Admin Service

Christian Schneider - Sat, 09/24/2011 - 09:09

Blog post edited by Christian Schneider

In the first part of the Karaf Tutorial we learned how to use maven and blueprint to offer and use pojo services and how to use the http service to publish a servlet.

In this second part we concentrate on configuration for our OSGi bundles. Unlike servlet containers OSGi contains a very good specification for configuration: The Config Admin Service from the OSGi enterprise spec. In this tutorial we will cover ussing the Config Admin Service with pure OSGi and blueprint and how to automatically deploy config files with your bundles.

The practical parts of this tutorial can be found on github in

The Configuration Admin Service spec

We will first get a fast overview of the Configuration Admin Service spec. There two main interfaces for us to use:

  • ConfigurationAdmin - Allows to retrieve and change configurations. This service is offered by the Config Admin Service implementation
  • ManagedService - Allows to react on configuration changes. You have to implement this and register it as a service to get notified

So basically a configuration in the Config Admin Service is a Dictionary that contains attributes and their values. The Dictionary is identified by a persistent identifier (pid). This is simply a String that should uniquely identify the configuration.

How to work with configuration?

While you can retrieve a configuration using the ConfigurationAdmin.getConfiguration interface I would not recommend to do so. OSGi is very dynamic so it may happen that your bundle starts before the config admin service or that the config admin service did not yet read the configuration. So you may end up sometimes getting Null for the configuration.

So the recommended way is to use a ManagedService and react on updates. If your bundle can not start without config then it is a good idea to create the pojo class to be configured on the first update received.

Introducing our very simple class to be configured

As we want to implement a clean style of how to work with configuration the class to be configured should be a pure pojo. While it is of course possible to simply implement the ManagedService interface and work with the Dictionary directly this will make you depend on OSGi and the current Config Admin Service spec. So instead we use a simple bean class that has a title property. Additionally I added a refresh method that should be called after all configuration was changed.

public class MyApp { String title; public void setTitle(String title) { this.title = title; } public void refresh() { System.out.println("Configuration updated (title=" + title + ")"); } }

So our goal is to configure the title when the configuration changes and then call refresh. We will do this in pure OSGi and in blueprint.

Get some practice. Working with configs using pure OSGi interfaces

The first practical part in this tutorial shows how to use the config admin service using just OSGi interfaces. While this is probably not the way you will do it later it helps to understand what happens under the hood.

You can find the implementation in the subdirectory configapp (

So we first need a pom file for the maven build. You best start with the pom from the configapp example.
If you start fresh you will have to use the maven-bundle-plugin to make your project a OSGi bundle and you need to add two dependencies:

<dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.compendium</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> <version>4.2.0</version> </dependency>

The first is for the config admin service interfaces and the second is to be able to create the Activator and contains the basic OSGi interfaces.

Now we will care about updating the MyApp class. The following little class does the trick. We implement the ManagedService interface to talk to the Config Admin Service. So we get called whenever the config changes. The first thing is to check for null as this can happen when the config is removed. We could a this point stop our MyApp but to keep it simple we just ignore those. The next step is to create the MyApp class. Normally you would do this in the Activator but then you would have to be able to work with an empty configuration which is not always desired. The last part is to simply call the setter with the value from the config and call refresh after all settings were made.

private final class ConfigUpdater implements ManagedService { public void updated(Dictionary config) throws ConfigurationException { if (config == null) { return; } if (app == null) { app = new MyApp(); } app.setTitle((String)config.get("title")); app.refresh(); } }

Of course this does not yet do anything. The last step is to register the ConfigUpdater in the Activator.start. We simply use registerService like for every other service. The only special thing is that you have to set the property SERVICE_PID to your config pid so the Config Admin Service knows what config you want to watch.

Hashtable<String, Object> properties = new Hashtable<String, Object>(); properties.put(Constants.SERVICE_PID, CONFIG_PID); serviceReg = context.registerService(ManagedService.class.getName(), new ConfigUpdater() , properties); Making this simple example run
  • build the project with mvn install.
  • Start a fresh Karaf instance
  • Copy the configapp.jar bundle from the target dir to the Karaf deploy dir

Now we notice that nothing seems to happen. Calling list in the Karaf console you should be able to see that the bundle is indeed started but it will not do create any output as there is no config.
We still need to create the config file and set the title.

  • copy the existing file /configadmin-features/src/main/resources/ConfigApp.cfg to the /etc dir of the Karaf instance

The important part here is that the filename has to be <pid>.cfg. So the config admin service will find it.

Now the fileinstall bundle will detect the new file in etc. As the ending is .cfg it will consider it to be a config admin resource and create or update the Config Admin Service configuration with the pid determined from the file name.

So you should now see the following in the Karaf console. This shows that the configuration change was correctly detected and forwarded. If you now change the file using an editor and save the change will alsobe propagated.

Configuration updated (title=" + title + ") Digging into the config with the Karaf config commands

Type the following in the Karaf console:

> config:list Pid: ConfigApp BundleLocation: file:/C:/java/apache-karaf-2.2.3/deploy/configapp.jar Properties: = ConfigApp felix.fileinstall.filename = file:/C:/java/apache-karaf-2.2.3/etc/ConfigApp.cfg title = my Title

Among other configs you should find the above config "ConfigApp". The config shows where it has been loaded from, the pid and of course all properties we set in the file.

We can also change the config:

> config:edit ConfigApp > config:propset title "A better title" > config:proplist = ConfigApp felix.fileinstall.filename = file:/C:/java/apache-karaf-2.2.3/etc/ConfigApp.cfg title = A better title > config:update Configuration updated (title=A better title)

We see that the change is directly propagated to our bundle. If you look into the config file in etc you can see that the change is also persisted to the file. So the change will still be there if we restart Karaf.

Configuration with Blueprint

After we have worked with the Config Admin Service in pure OSGi we will now look how the same can be achieved in Blueprint. Fortunately this is quite easy as Blueprint does most of the work for us.

We simply define a cm:property-placeholder element. This works similar to property place holder with files but works with the Config Admin Service. We need to supply the config PID and the update strategy.
As strategy we select "reload". This means that after a change the blueprint context is reloaded to reflect the changes. We also set default properties that will be used when the config PID is not found or an attribute is not present.

The integration with our bean class is mostly a simple bean definition where we define the title property and assign the placeholder which will be resolved using the config admin service. The only special thing is the init-method. This is used to give us the chance to react after all changes were made like in the pure OSGi example.

For bluenprint we do not need any maven dependencies as our Java Code is a pure Java bean. The blueprint context is simply activated by putting it in the OSGI-INF/blueprint directory and by having the blueprint extender loaded. As blueprint is always loaded in Karaf we do not need anything else.

<blueprint xmlns="" xmlns:cm="" xmlns:xsi="" xsi:schemaLocation=" [] [] [] [] "> <cm:property-placeholder persistent-id="ConfigApp" update-strategy="reload" > <cm:default-properties> <cm:property name="title" value="Default Title"/> </cm:default-properties> </cm:property-placeholder> <bean id="myApp" init-method="refresh"> <property name="title" value="$\{title\}"></property> </bean> </blueprint>

In the above xml please remove the backslashes around title. This is just to avoid confluence interpreting it as a wiki macro.

Deploying config files

After we have successfully used the Config Admin Service the only thing that remains to go into production is to deploy our bundle together with a default configuration. This can be done using a Karaf feature file. We define our feature with the bundles it needs and simply add a configfile element. This makes Karaf deploy the given file into the etc directory of our Karaf installation. If the file is already present then it will not be overwritten.

<feature name="tutorial-configadmin" version="${pom.version}"> <bundle>${pom.version}</bundle> <bundle>${pom.version}</bundle> <configfile finalname="/etc/ConfigApp.cfg">${pom.version}/cfg</configfile> </feature>

So one last question is how to deploy the config to maven for the configfile element to find it. This happens like for the feature with the build-helper-maven-plugin in Karaf See the pom file for details how to use it.

Summing it up and a look into the future

During this tutorial we have learned how the Config Admin Service works and how to use it with pure OSGi and blueprint. We have also seen how to build and deploy our projects together with documentation.

While this is already very usefull some small things are missing in my opinion. The first thing is that configfile does not really seem to be consistent with the config admin service. In fact Karaf does not use the config admin service to deploy the file. So what I would like to see is that the also existing config element not only writes the config to the config admin service but also persists it. Fortunately my colleague Jean Baptiste is already working on this. See

The other thing is that for enterprise environments a config admin service with some additional features is needed. One thing is that it should be possible to do configuration on a whole network of servers with a central source for configuration and a nice UI. The other thing is that you would like to not only deploy the default config but also the config the admin really wants for the system. So I  imagine that you should be able to define a deployment plan with bundles and features to install but also with the required configuration changes. If this is done right it will allow good audits of deployment and config changes and will also allow an admin to roll back a change in case something goes wrong. I hope we can provide some of this in one of the next Talend ESB EE releases.

View Online | Add Comment
Categories: Christian Schneider

Talend donates Security Token Service (STS) to Apache CXF

Colm O hEigeartaigh - Fri, 09/23/2011 - 16:31
I am pleased to announce that Talend has donated a Security Token Service (STS) implementation to Apache CXF, which will be part of the forthcoming 2.5 release. Since the 2.4.0 release, CXF ships with an STS framework (in the ws-security module), as well as a simple implementation of the framework in the examples. The STS that Talend has donated to the community is a sophisticated implementation of the STS framework that builds on top of CXF's existing mature security functionality.

In future blog posts I will document the features of the STS and how to configure it, as well as walk through some system tests. Here are some of the features and standards that the new STS supports:
  • WS-Trust 1.3/1.4
  • WS-SecurityPolicy1.3
  • Authentication Mechanisms for a RST:UsernameToken, SAML token (1.1/2.0), KerberosToken, X.509 Token.
  • Security Binding supported: Symmetric,Asymmetric, Transport 
  • Supports WS-Trust Issue/Validate and Cancel binding 
  • Can issue the following tokens:SAML 1.1/2.0Holder-Of-Key/Bearer, SecurityContextTokens, Custom Tokens.
  • Issued token can be encrypted 
  • Validate binding supports issuing a new token (token transformation).
  • Custom Validators can be implemented 
  • Creation of SAML tokens can be customized.
  • Advanced RST elements:KeyType (Public, Symmetric, Bearer), Entropy (Symmetric, Public) , OnBehalfOf, ActAs, Claims, SecondaryParameters
  • Pluggable claims handling and management
Categories: Colm O hEigeartaigh


Subscribe to Talend Community Coders aggregator