Latest Activity

Apache CXF STS documentation - part I

Colm O hEigeartaigh - Wed, 10/19/2011 - 18:00
The forthcoming Apache CXF 2.5 release will have an STS (Security Token Service) implementation which has been donated by Talend. This is the first in a series of blog posts where I will be going into the STS implementation in detail. In this post I will be explaining what an STS is and talking about the STS provider framework in CXF.

1) What is a Security Token Service?

An informal description of a Security Token Service is that it is a web service that offers some or all of the following services (amongst others):
  • It can issue a Security Token of some sort based on presented or configured credentials.
  • It can say whether a given Security Token is valid or not
  • It can renew (extend the validity of) a given Security Token
  • It can cancel (remove the validity of) a given Security Token
  • It can transform a given Security Token into a Security Token of a different sort.
Offloading this functionality to another service greatly simplifies client and service provider functionality, as they can simply call the STS appropriately rather than have to figure out the security requirements themselves. For example, the WSDL of a service provider might state that a particular type of security token is required to access the service. A client of the service can ask an STS for a Security Token of that particular type, which is then sent to the service provider. The service provider could choose to validate the received token locally, or dispatch the token to an STS for validation. These are the two most common use-cases of an STS.

A client can communicate with the STS via a protocol defined in the WS-Trust specification. The SOAP Body of the request contains a "RequestSecurityToken" element that looks like:

<wst:RequestSecurityToken Context="..." xmlns:wst="...">
    <wst:TokenType>...</wst:TokenType>
    <wst:RequestType>...</wst:RequestType>
    <wst:SecondaryParameters>...</wst:SecondaryParameters>
    ...
</wst:RequestSecurityToken>

The Apache CXF STS implementation supports a wide range of parameters that are passed in the RequestSecurityToken element. The SOAP Body of the response from the STS will contain a "RequestSecurityTokenResponse(Collection)" element, e.g.:

<wst:RequestSecurityTokenResponseCollection xmlns:wst="...">
    <wst:RequestSecurityTokenResponse>
    ...
    </wst:RequestSecurityTokenResponse>
</wst:RequestSecurityTokenResponseCollection>

1.1 A sample request/response for issuing a Security Token

A sample client request is given here, where the client wants the STS to issue a SAML 2.0 token for the "http://cxf.apache.org:8080/service" service:

<wst:RequestSecurityToken Context="..." xmlns:wst="...">
    <wst:TokenType>
       http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
    </wst:TokenType>
    <wst:RequestType>
        http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue
    </wst:RequestType>
    <wsp:AppliesTo>http://cxf.apache.org:8080/service</wsp:AppliesTo>
</wst:RequestSecurityToken>

The STS responds with:

<wst:RequestSecurityTokenResponseCollection xmlns:wst="...">
    <wst:RequestSecurityTokenResponse>
         <wst:TokenType>
         http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
         </wst:TokenType>
         <wst:RequestedSecurityToken>
             <saml2:Assertion xmlns:saml2="..." ... />
         </wst:RequestedSecurityToken>
    </wst:RequestSecurityTokenResponse>
</wst:RequestSecurityTokenResponseCollection>

2) The STS provider framework in Apache CXF

The first support for an STS in Apache CXF appeared in the 2.4.0 release with the addition of an STS provider framework in the WS-Security module. This is essentially an API that can be used to create your own STS implementation. As the STS implementation shipped in CXF 2.5 is based on this provider framework, it makes sense to examine it in more detail.

The SEI (Service Endpoint Interface) is available here. It contains the following methods that are relevant to the STS features discussed above:
  • RequestSecurityTokenResponseCollectionType issue(RequestSecurityTokenType request) - to issue a security token
  • RequestSecurityTokenResponseType issueSingle( RequestSecurityTokenType request) - to issue a security token that is not contained in a "Collection" wrapper (for legacy applications).
  • RequestSecurityTokenResponseType cancel(RequestSecurityTokenType request) - to cancel a security token
  • RequestSecurityTokenResponseType validate(RequestSecurityTokenType request) - to validate a security token
  • RequestSecurityTokenResponseType renew(RequestSecurityTokenType request) - to renew a security token
The SEI implementation handles each request by delegating it to a particular operation, which is just an interface that must be implemented by the provider framework implementation. Finally, a JAX-WS provider is available, which dispatches a request to the appropriate operation.

Significant updates to the STS Provider framework after the CXF 2.4.0 release include support for SOAP 1.2, a major bug fix to support operations other than issue,  better exception propagation, and adding support for the WS-Trust 1.4 schema. These features are all available in the Apache CXF 2.4.3 release onwards.
Categories: Colm O hEigeartaigh

Camel presentation from the SOA and BPM days in Düsseldorf

Christian Schneider - Wed, 10/19/2011 - 16:45

Blog post added by Christian Schneider

Last week I was at the SOA / BPM days in Düsseldorf and talked about Camel Architecture and showed some practical examples. Some of the highlights were:

  • Getting started with Apache Camel. Download, First project, run in Eclipse
  • Make your project fit for OSGi
  • Deployment on Karaf and showing the new Camel commands for the Karaf shell
  • How to test and debug Camel Routes?
  • Using Camel to do very light weight XML Messaging over several transports like file and jms (will describe this in a separate blog post)

You can find my (partly) german slides here: workshop_messagebasierte_webservices_camel.pdf

The examples are on github: https://github.com/cschneider/examples-cxf-camel-soabpmdays

View Online | Add Comment
Categories: Christian Schneider

Adding X.509 security headers to Metro SOAP calls

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

This tutorial shows how to modify the Metro version of the WSDL-first DoubleIt Example to include WS-Security (WSS) with X.509 public key certificates. The source code for this tutorial is located here. Of course don't use the included keys--or sample passwords--for production, also note this tutorial may have errors so make sure all work is carefully tested before production deployment.

  1. Create key pairs for the client and the web service provider. Follow the OpenSSL and Metro tutorial for this step. Note this will generate self-signed keys, sufficient for tutorial purposes but for production you'll most probably want third party CA-signed keys instead. Place the client and server key in the root directory of the DoubleIt project.

  2. Modify the WSDL to require encryption and signatures from both directions. To do this, we will create a temporary project in the NetBeans IDE and use it to modify the DoubleIt.wsdl file. Follow Steps #2-#3 in the Metro/UsernameToken tutorial for this process, except for Substep #3 under Step #3. Here, under the "Edit Web Service Attributes" section, select "Mutual Certificates Security", and for the Configure options, check the Metro guide to see what best fits your needs. For the purposes of this tutorial, I chose Basic 128 bit encryption and encrypted signature as shown in the illustration below.

    For the key information, unselect "Use Development Defaults", select the Keystore button and supply the JKS service keystore file name, store password, key alias and key password of the service key you created in Step #1 above. The Alias Selector class can be left blank. Next, press the truststore button and provide the truststore and truststore password. The Alias field can be left blank because we're accepting any client-side certificates in the truststore, as well as the Certificate Selector field, unused in this tutorial. If you followed the OpenSSL tutorial in Step #1 in creating your keys, the truststore will be the same as the keystore (servicestore.jks).

    The modified WSDL generated by NetBeans is shown below. The bolded elements show the keystore information you just entered--note this information can be manually edited without needing to use the above NetBeans wizard.

    <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="DoubleIt" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:di="http://www.example.org/schema/DoubleIt" xmlns:tns="http://www.example.org/contract/DoubleIt" targetNamespace="http://www.example.org/contract/DoubleIt" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:fi="http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service" xmlns:tcp="http://java.sun.com/xml/ns/wsit/2006/09/policy/soaptcp/service" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sc="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"> <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/schema/DoubleIt"> <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="http://schemas.xmlsoap.org/soap/http" /> <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"/> <sp:AsymmetricBinding> <wsp:Policy> <sp:InitiatorToken> <wsp:Policy> <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:WssX509V3Token10/> </wsp:Policy> </sp:X509Token> </wsp:Policy> </sp:InitiatorToken> <sp:RecipientToken> <wsp:Policy> <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"> <wsp:Policy> <sp:WssX509V3Token10/> <sp:RequireIssuerSerialReference/> </wsp:Policy> </sp:X509Token> </wsp:Policy> </sp:RecipientToken> <sp:Layout> <wsp:Policy> <sp:Strict/> </wsp:Policy> </sp:Layout> <sp:IncludeTimestamp/> <sp:OnlySignEntireHeadersAndBody/> <sp:AlgorithmSuite> <wsp:Policy> <sp:Basic128/> </wsp:Policy> </sp:AlgorithmSuite> <sp:EncryptSignature/> </wsp:Policy> </sp:AsymmetricBinding> <sp:Wss10> <wsp:Policy> <sp:MustSupportRefIssuerSerial/> </wsp:Policy> </sp:Wss10> <sc:KeyStore wspp:visibility="private" location="/home/gmazza/dataExt3/talendwork/DoubleItX509Metro/servicestore.jks" type="JKS" storepass="sspass" alias="myservicekey" keypass="skpass"/> <sc:TrustStore wspp:visibility="private" storepass="sspass" type="JKS" location="/home/gmazza/dataExt3/talendwork/DoubleItX509Metro/servicestore.jks"/> </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="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="AckRequested" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="SequenceAcknowledgement" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="Sequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="CreateSequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> </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="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="AckRequested" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="SequenceAcknowledgement" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="Sequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="CreateSequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> </sp:SignedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </wsdl:definitions>

    As you can see, the WSDL has been modified with new Policy elements added at the end, as well as references to those elements within the wsdl:binding section. The elements are defined in OASIS' WS-SecurityPolicy specification. The wsdl:binding section has two types of policy references: a single wsdl:binding-level policy which specifies the need for encryptions and/or signatures, and two wsdl:operation-level policies which specify the elements of the SOAP request and response that need to be encrypted and/or signed.

  3. Configure the client certificate information. Follow Step #5 of the UsernameToken tutorial for this process, except replace Substep #3 with the below:

    3. Within the Project View of the project, go to Web Service References -> DoubleIt, and right-click on the latter. Choose "Edit Web Service Attributes", and go to the Quality Of Service Tab | Security section. To use the keys you created in Step #2 above, select the Keystore button and supply the JKS client keystore, client store password, alias for the client key and client key password. Then select Truststore and supply the same JKS keystore and store password, but the service key for the alias, as that is the only key the SOAP client is to trust. (The certificate selector can be again left blank.) Click OK to close the wizard.

    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="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="mainclientconfig" > <import location="DoubleIt.xml" namespace="http://www.example.org/contract/DoubleIt"/> </definitions>

    DoubleIt.xml - This is really just the service WSDL, except the Policy section at the bottom has changed from providing service-side requirements to client-side configuration information. Bolded below is the certificate information for the client you had entered earlier.

    <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions name="DoubleIt" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:di="http://www.example.org/schema/DoubleIt" xmlns:tns="http://www.example.org/contract/DoubleIt" targetNamespace="http://www.example.org/contract/DoubleIt" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:fi="http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service" xmlns:tcp="http://java.sun.com/xml/ns/wsit/2006/09/policy/soaptcp/service" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sc="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" xmlns:sc1="http://schemas.sun.com/2006/03/wss/client"> <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/schema/DoubleIt"> <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="http://schemas.xmlsoap.org/soap/http" /> <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="http://localhost:8080/doubleit/services/doubleit"/> </wsdl:port> </wsdl:service> <wsp:Policy wsu:Id="DoubleItBindingPolicy"> <wsp:ExactlyOne> <wsp:All> <sc1:KeyStore wspp:visibility="private" alias="myclientkey" keypass="ckpass" storepass="cspass" type="JKS" location="/home/gmazza/dataExt3/talendwork/DoubleItX509Metro/clientstore.jks"/> <sc1:TrustStore wspp:visibility="private" peeralias="myservicekey" storepass="cspass" type="JKS" location="/home/gmazza/dataExt3/talendwork/DoubleItX509Metro/clientstore.jks"/> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> </wsdl:definitions>
  4. Bring the NetBeans-generated configuration files back to your Maven project. Be sure that you copied over the service wsdl and client-side configuration files to your Maven project as explained at the end of Steps #3 and #5 of the Metro/UsernameToken tutorial.

  5. Test the client. After deploying the servlet as described in Step #8 the WSDL-first tutorial, run the client as shown in Step #10 of that tutorial and make sure you see the doubled number responses. You can see the SOAP requests and responses by activating the debug output as shown in the comments for the exec-maven-plugin in the client/pom.xml file. My results for the first client call:

    SOAP Request: ---[HTTP request - http://localhost:8080/doubleit/services/doubleit]--- Accept: text/xml, multipart/related Content-Type: text/xml; charset=utf-8 SOAPAction: "http://www.example.org/contract/DoubleIt/DoubleItPortType/DoubleItRequest" 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="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <S:Header> <To xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5005">http://localhost:8080/doubleit/services/doubleit </To> <Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1" wsu:Id="_5004">http://www.example.org/contract/DoubleIt/DoubleItPortType/DoubleItRequest </Action> <ReplyTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5003"> <Address>http://www.w3.org/2005/08/addressing/anonymous </Address> </ReplyTo> <MessageID xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5002">uuid:6d3c7cbc-1ae6-4112-89b3-3b2ef9dc7fa1</MessageID> <wsse:Security S:mustUnderstand="1"> <wsu:Timestamp xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" wsu:Id="_3"> <wsu:Created>2011-10-18T01:55:35Z</wsu:Created> <wsu:Expires>2011-10-18T02:00:35Z</wsu:Expires> </wsu:Timestamp> <wsse:BinarySecurityToken xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="uuid_bd95d424-e86d-4d5c-8fb1-7fcae868bf44">MIIDzjCCAzeg...truncated...khfwn5DgquTnQsQStP </wsse:BinarySecurityToken> <xenc:EncryptedKey xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" Id="_5007"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" /> <ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="KeyInfoType"> <wsse:SecurityTokenReference> <ds:X509Data> <ds:X509IssuerSerial> <ds:X509IssuerName>EMAILADDRESS=server@sample.com, CN=Server, O=Sample Service Key - NOT FOR PRODUCTION USE, L=Niagara Falls, ST=New York, C=US </ds:X509IssuerName> <ds:X509SerialNumber>9762824747457659410 </ds:X509SerialNumber> </ds:X509IssuerSerial> </ds:X509Data> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>LywTT/TxQbuZf/a+VnZJ...truncated...vrXbdBAP+ZfM38HggKbwlEPrgw= </xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#_5008" /> <xenc:DataReference URI="#_5009" /> </xenc:ReferenceList> </xenc:EncryptedKey> <xenc:EncryptedData xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" Id="_5009" Type="http://www.w3.org/2001/04/xmlenc#Element"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue>vgZu17v9KRAodnd7O...truncated...z6jPvjctlxjOGHGn2iGI0w== </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </wsse:Security> </S:Header> <S:Body wsu:Id="_5006"> <xenc:EncryptedData xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" Id="_5008" Type="http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue>jc+U3gkWZUX4W9heZ/og...truncated...p4qBPco1iOXXVTZunZjpm </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </S:Body> </S:Envelope> SOAP Response: http://localhost:8080/doubleit/services/doubleit - 200]--- null: HTTP/1.1 200 OK Content-Type: text/xml;charset=utf-8 Date: Tue, 18 Oct 2011 01:55:36 GMT Server: Apache-Coyote/1.1 Transfer-Encoding: chunked <?xml version='1.0' encoding='UTF-8'?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> <S:Header> <To xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5005">http://www.w3.org/2005/08/addressing/anonymous </To> <Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1" wsu:Id="_5003">http://www.example.org/contract/DoubleIt/DoubleItPortType/DoubleItResponse </Action> <MessageID xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5002">uuid:43bfe620-bda9-4400-ba3e-ad2511a0a7dc</MessageID> <RelatesTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5004">uuid:6d3c7cbc-1ae6-4112-89b3-3b2ef9dc7fa1</RelatesTo> <wsse:Security S:mustUnderstand="1"> <wsu:Timestamp xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" wsu:Id="_3"> <wsu:Created>2011-10-18T01:55:36Z</wsu:Created> <wsu:Expires>2011-10-18T02:00:36Z</wsu:Expires> </wsu:Timestamp> <xenc:EncryptedKey xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" Id="_5007"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" /> <ds:KeyInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="KeyInfoType"> <wsse:SecurityTokenReference> <ds:X509Data> <ds:X509IssuerSerial> <ds:X509IssuerName>EMAILADDRESS=bobclient@sample.com, CN=Bob Client, O=Sample Client Key - NOT FOR PRODUCTION USE, L=Buffalo, ST=New York, C=US </ds:X509IssuerName> <ds:X509SerialNumber>16785336678514363577 </ds:X509SerialNumber> </ds:X509IssuerSerial> </ds:X509Data> </wsse:SecurityTokenReference> </ds:KeyInfo> <xenc:CipherData> <xenc:CipherValue>QHA5mJrSkmLVHDunj/e5YCFy...truncated...1NENqYs4xOHXKcRPF01gx9GU= </xenc:CipherValue> </xenc:CipherData> <xenc:ReferenceList> <xenc:DataReference URI="#_5008" /> <xenc:DataReference URI="#_5009" /> </xenc:ReferenceList> </xenc:EncryptedKey> <xenc:EncryptedData xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" Id="_5009" Type="http://www.w3.org/2001/04/xmlenc#Element"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue>IWSl4Hrxe0UsnKCQxnVlit...truncated...21oLUvP+aVa7L1PlstRt2U= </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </wsse:Security> </S:Header> <S:Body wsu:Id="_5006"> <xenc:EncryptedData xmlns:ns17="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns16="http://www.w3.org/2003/05/soap-envelope" Id="_5008" Type="http://www.w3.org/2001/04/xmlenc#Content"> <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" /> <xenc:CipherData> <xenc:CipherValue>wbM0ndRU+Q/9EqW9Af2bUXpJaON1...truncated...ne4DBocqTuY1XCxEy4Vq5Q== </xenc:CipherValue> </xenc:CipherData> </xenc:EncryptedData> </S:Body> </S:Envelope> -------------------- The number 10 doubled is 20
Notes:
  1. As can be seen from the client- and service-side keystore configuration listed above, Metro uses a absolute file path when specifying keystores, making samples nonportable from machine to machine. To get around this issue, the source code download has been modified a bit to take advantage of Maven resource filtering to make a runtime change of the absolute paths depending on where the sample has been extracted.
  2. For more information on WS-SecurityPolicy, see this WSO2 article as well as the OASIS WS-SecurityPolicy Examples guide.
  3. When running the SOAP client you'll probably see warning messages like the below, indicating the client can see the service-side specific keystore configuration information but of course cannot use it: WARNING: WSP0075: Policy assertion "{http://schemas.sun.com/2006/03/wss/server}KeyStore" was evaluated as "UNSUPPORTED". Oct 17, 2011 9:55:34 PM [com.sun.xml.ws.policy.EffectiveAlternativeSelector] selectAlternatives WARNING: WSP0075: Policy assertion "{http://schemas.sun.com/2006/03/wss/server}TrustStore" was evaluated as "UNSUPPORTED". Oct 17, 2011 9:55:34 PM [com.sun.xml.ws.policy.EffectiveAlternativeSelector] selectAlternatives WARNING: WSP0019: Suboptimal policy alternative selected on the client side with fitness "PARTIALLY_SUPPORTED". These messages can be ignored for the purposes of this tutorial as it is just a consequence of the DoubleIt project's usage of the same WSDL file for the client and web service provider--see the Metro/UsernameToken Notes for more information.
Categories:

Configure LDAP directory for CXF STS

Oliver Wulff - Tue, 10/18/2011 - 07:15
I explained in my previous blog how to set up the CXF STS where you manage your users and claims in a file.This blog explains the required changes to integrate the CXF STS with a LDAP directory.

You can attach an LDAP directory either for username/password validation or for retrieving the claims data or both.

1. Username and password authentication

WSS4j supports username/password authentication against a JAAS based backend since version 1.6.3.

The JDK provides a JAAS LoginModule for LDAP which can be configured as illustrated here in a sample jaas configuration (jaas.config):
  
myldap {
 com.sun.security.auth.module.LdapLoginModule REQUIRED
 userProvider=ldap://ldap.mycompany.org:389/OU=Users,DC=mycompany,DC=org"
 authIdentity="cn={USERNAME},OU=Users,DC=mycompany,DC=org"
 useSSL=false
 debug=true;
};

You can get more information about this LoginModule here.

In this example, all the users are stored in the organization unit Users within mycompany.org. The configuration filename can be chosen, i.e. jaas.config. The filename must be configured as a JVM argument. I recommend to set JVM related configurations for Tomcat in the setenv.sh/bat file located in tomcat/bin directory. This script is called by catalina.bat/sh implicitly and might look like this for UNIX:

#!/bin/sh JAVA_OPTS="-Djava.security.auth.login.config=/opt/tomcat/conf/jaas.config"export JAVA_OPTS

Now, the LDAP LoginModule is configured. Next we have to configure the JAASUsernameTokenValidator for the STS endpoint.

<bean
  class="org.apache.ws.security.validate.JAASUsernameTokenValidator"
      id="jaasUTValidator">
   <property name="contextName" value="myldap"/>
</bean>

<jaxws:endpoint id="transportSTSUT"
  endpointName="ns1:TransportUT_Port"
  serviceName="ns1:SecurityTokenService"
  xmlns:ns1=http://docs.oasis-open.org/ws-sx/ws-trust/200512/
  wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
  address="/STSServiceTransportUT"
  implementor="#transportSTSProviderBean">

  <jaxws:properties>
    <entry key="ws-security.ut.validator"
         value-ref="jaasUTValidator"/>
  </jaxws:properties>
</jaxws:endpoint>

The property contextName must match with the context name defined in the JAAS configuration file which is "myldap" in this example.
<
 2. Claims management

When a STS client requests a claim, the ClaimsManager in the STS checks every registered ClaimsHandler who can provide the data of the requested claim.  The CXF STS provides a claims handler implementation which allows to add claims which are stored as user attributes in a LDAP directory. You can configure which claim URI maps to which LDAP user attribute. The implementation uses the spring ldap module (LdapTemplate).

<util:list id="claimHandlerList">
  <ref bean="ldapClaimsHandler" />
</util:list>

<bean id="contextSource"
   class="org.springframework.ldap.core.support.LdapContextSource">
  <property name="url" value="ldap://ldap.mycompany.org:389" />
  <property name="userDn"
    value="CN=techUser,OU=Users,DC=mycompany,DC=org" />
  <property name="password" value="mypassword" />
</bean>

<bean id="ldapTemplate"
   class="org.springframework.ldap.core.LdapTemplate">
  <constructor-arg ref="contextSource" />
</bean>

<util:map id="claimsToLdapAttributeMapping">
  <entry
key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
value="givenName" />
  <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
value="sn" />
  <entry
key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
value="mail" />
  <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country"
value="c" />
</util:map>

<bean id="ldapClaimsHandler"
    class="org.apache.cxf.sts.claims.LdapClaimsHandler">
  <property name="ldapTemplate" ref="ldapTemplate" />
  <property name="claimsLdapAttributeMapping"
            ref="claimsToLdapAttributeMapping" />
  <property name="userBaseDN"
      value="OU=Users,DC=mycompany,DC=org" />
</bean>

The claim id's are configured according to chapter 7.5 in the specification Identity Metasystem Interoperability. You can add as many entries in the map claimsToLdapAttributeMapping as you want. Thus you can add any user attribute from your LDAP directory to the issued SAML token.

Categories: Oliver Wulff

What&#8217;s new in Karaf 2.2.4 ?

Jean-Baptiste Onofré - Mon, 10/17/2011 - 10:45
Apache Karaf 2.2.4 has been released this week end. You can take a look on the release notes. More than a bug fixes release, this version includes several new features and enhancements. Command aliases Previously, the osgi:* commands gathered different kind of usage: osgi:start, osgi:stop, etc are related to bundles, osgi:shutdown is related to container [...]
Categories: Jean-Baptiste Onofré

Web services links (16 October 2011)

Glen Mazza - Mon, 10/17/2011 - 04:28

Web Service related links of interest this week:

Karaf related links:

Categories:

Configure and deploy Identity Provider (IdP) - Part II

Oliver Wulff - Thu, 10/13/2011 - 14:30
In my previous blog I talked about setting an STS which supports username/password authentication and the issuance of a SAML 2.0 token which contains additional claims information.
We need these claims information to provide the application (called Relying Party in WS-Federation specification) the information like application roles for role based access control. Claims based authorization goes one step further and provides other claims data of the authenticated entity (SAML subject).

Introduction

This blog is about the Identity Provider (IDP) implementation which is referenced in the WS-Federation specification. Therefore, I'm giving a short introduction. This blog series looks at the passive requestor profile only of WS-Federation.

The following picture is used by Microsoft which supports WS-Federation in their Windows Identity Foundation framework.


(C) Microsoft



The key principals of WS-Federation are:
  • Externalize authentication process from the application container
  • Provide the claims/attributes of the authenticated identity to the application for role based and fine grained authorization
WS-Federation gives you the following benefits:
  • Applications can benefit of stronger security mechanism without changes
  • Identities/users don't have to be provisioned in all security domains to propagate identities across the security domains
  • B2B partners can be integrated without changing the application (includes programming and configuration)
  • Audit-Trail end-to-end


    Deploy Identity Provider (IdP)



    This sample IDP will support the following functionality:
    • Authentication based on username/password (Basic Authentication)
    • The authentication store is configured in the STS and can be file based (part of this example) or LDAP
    • Following federation parameters are supported:
      • wtrealm
      • wreply
      • wctx
      • wresult
    • Required claims can be configured per Relying Party (based on wtrealm value)
    Jürg Portmann and myself have put together this IDP based on Maven which can be downloaded here.


    1. Claims configuration per relying party

    The required claims per relying party are configured in the WEB-INF/RPClaims.xml. The XML file has the following structure. The key of each map entry must match with the wtrealm paramater in the redirect triggered by the relying party.
    (the set up of the relying part will be covered in the next blog).


        <util:map id="realm2ClaimsMap">
            <entry key="http://localhost:8080/wsfedhelloworldother/"
                value-ref="claimsWsfedhelloworld" />
            <entry key="http://localhost:8080/wsfedhelloworld/"
                value-ref="claimsWsfedhelloworldother" />
        </util:map>

        <util:list id="claimsWsfedhelloworld">
            <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
            </value>
            <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
            </value>
        </util:list>

        <util:list id="claimsWsfedhelloworldother">
            <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
            </value>
            <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
            </value>
            <value>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
            </value>
        </util:list>   

    You group the required claims in beans which are a list of String as illustrated in claimsWsfedhelloworld and claimsWsfedhelloworldother.

    The map bean must be named realm2ClaimsMap and maps the different relying parties (applications) to one of the claim lists.


    In a further release, this information will be pulled from a WS-Federation Metadata document published by the replying party.


    2. Project dependencies
     
    The IDP reuses a lot of existing projects like Apache CXF to communicate with the STS for instance and provides an adaption of the WS-Trust interface to pure HTTP functionality as it is supported by a browser. The IDP has the following dependencies in the Maven project:

        <properties>
          <cxf.version>2.5.0-SNAPSHOT</cxf.version>
       </properties>
       <dependencies>        <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-transports-http</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-frontend-jaxws</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-ws-policy</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-ws-security</artifactId>
                <version>${cxf.version}</version>
            </dependency>
       </dependencies>  


    3. IDP web application configuration

    Setting up the IDP involves a few steps only. If you you don't deploy the IDP in the same servlet container as the STS you must first download Tomcat 7 and update server.xml. If you deploy the IDP in the same servlet container you can skip 3.1

    3.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"
                   keystoreFile="tomcatKeystore.jks"
                   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.

    3.2 Configure Username/password authentication


    As described in section 1. the requested claims per relying party are managed in the file WEB-INF/RPclaims.xml.

    3.3 IDP and STS distributed
     
    If the IDP and STS are not deployed on the same machine (likewise in production) you have to update the following configuration:






    1) The remote WSDL location of the STS:

    WEB-INF/web.xml:

      <init-param>
        <param-name>sts.wsdl.url</param-name>
        <param-value>https://localhost:9443/wsfedidpsts/STSService?wsdl</param-value>
      </init-param>

    2) the transport conduit to enable the truststore as described in more detail here:


    WEB-INF/beans.xml
      <http:conduit name="https://localhost:9443/.*">
        <http:tlsClientParameters disableCNCheck="true">
          <sec:trustManagers>
            <sec:keyStore type="jks" password="cspass" resource="clientstore.jks"/>
          </sec:trustManagers>
        </http:tlsClientParameters>
      </http:conduit>



    3) fully qualified realm in realm2ClaimsMap


    As described in 1) the key of an entry in the map realm2ClaimsMap must match with the  parameter wtrealm in the redirect triggered by the relying party. If you access the relying party using a fully qualified URL, you must use the fully qualified URL in the IDP too.  


    WEB-INF/RPclaims.xml


        <util:map id="realm2ClaimsMap">
            <entry key="http://localhost:8080/wsfedhelloworldother/"
                value-ref="claimsWsfedhelloworld" />
            <entry key="http://localhost:8080/wsfedhelloworld/"
                value-ref="claimsWsfedhelloworld2" />
        </util:map>



    4. Deploy the IDP to Tomcat

    To deploy the IDP using Maven you have to follow these steps:
    • Configuring the following maven plugin    <plugin>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>tomcat-maven-plugin</artifactId>
              <version>1.1</version>
              <configuration>
                   <server>myTomcat</server>
                   <url>http://localhost:9080/manager/text</url>
                   <path>/${project.build.finalName}</path>
              </configuration>
          </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:
        <url>http://localhost:9080/manager</url>


    4. Test the IDP

    As long as you don't have a relying party in place you can't easily test the IDP. My next post will explain the set up of the relying party using Tomcat 7. Stay tuned.


    If you like you can test the IDP by using an HTTP client and pass the following request parameters (urls must be encoded):

    wa       wsignin1.0wreply   http://localhost:8080/wsfedhelloworld/secureservlet/fedwtrealm  http://localhost:8080/wsfedhelloworld/

    The browser will get a HTML form back (auto-submit). The action of the form is equal to the value of wreply which doesn't exist. You see the response of the STS escaped in the form parameter wresult.
    Categories: Oliver Wulff

    Using Kerberos with Web Services - part II

    Colm O hEigeartaigh - Tue, 10/11/2011 - 18:03
    This is the second of a two-part series on using Kerberos with Web Services, with Apache WSS4J and CXF. Part I showed how to set up a KDC distribution, and how to generate client and service principals to use in some CXF system tests. The system tests showed how to obtain a Kerberos token from a KDC, package it in a BinarySecurityToken, and send it to a service endpoint for validation. In other words, part I illustrated how to use Kerberos for client authentication in a web service setting.

    This article builds on part I by showing how to use the secret key associated with a Kerberos Token to secure (sign and encrypt) the request. This functionality was added as part of WSS4J 1.6.3, and the related WS-SecurityPolicy functionality was released as part of CXF 2.4.3.

    1) Setting up the Kerberos system tests in Apache CXF 

    If you have not done so already, follow the instructions in part I to install a Kerberos distribution and to generate client and service principals to run the CXF Kerberos system tests. The KerberosTokenTest in Apache CXF contains a number of different Kerberos tests. In this article we will examine the tests that involve obtaining a Kerberos Token, and using the associated secret key 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 https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/1.1) Installing a custom KerberosTokenDecoder

    Once the client obtains an AP-REQ token from the KDC, the client also has easy access to the session key, which can be used to secure the request in some way. Unfortunately, there appears to be no easy way to obtain the session key on the receiving side. WSS4J does not support extracting a Kerberos session key on the receiving side to decrypt/verify a secured request out-of-the-box. Instead, a KerberosTokenDecoder interface is provided, which defines methods for setting the AP-REQ token and current Subject, and a method to then get a session key. An implementation must be set on the KerberosTokenValidator to obtain a session key to decrypt or verify a signed request.

    To run the Kerberos system tests that require a secret key on the receiving side, download an implementation of the KerberosTokenValidator interface here, and copy it to "systests/ws-security/src/test/java/org/apache/cxf/systest/ws/kerberos/server". The implementation is based on code written by the Java Monkey, and uses internal sun APIs, and so can't be shipped in Apache CXF/WSS4J. Once this implementation has been copied into the ws-security module, then you must compile or run any tests with the "-Pnochecks" profile enabled, as otherwise the code fails checkstyle.

    Open the server configuration file ("src/test/resources/org/apache/cxf/systest/ws/kerberos/server/server.xml"), and uncomment the "kerberosTicketDecoderImpl" bean, and the property of the "kerberosValidator" bean that refers to it:
    <bean id="kerberosTicketDecoderImpl"   class="org.apache.cxf.systest.ws.kerberos.server.KerberosTokenDecoderImpl"/>
     
    <bean id="kerberosValidator"
           class="org.apache.ws.security.validate.KerberosTokenValidator">
            <property name="contextName" value="bob"/>
            <property name="serviceName" value="bob@service.ws.apache.org"/>
            <property name="kerberosTokenDecoder" ref="kerberosTicketDecoderImpl"/>
    </bean> 1.2) Running the tests

    Open KerberosTokenTest.java and comment out the "@org.junit.Ignore" entries for the last four tests, "testKerberosOverTransportEndorsing", "testKerberosOverAsymmetricEndorsing", "testKerberosOverSymmetricProtection" and "testKerberosOverSymmetricDerivedProtection". Finally, run the tests via:
    mvn -Pnochecks test -Dtest=KerberosTokenTest -Djava.security.auth.login.config=src/test/resources/kerberos.jaas 2) The tests in more detail

    In this section, we'll look at the tests in more detail. 

    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:
    • testKerberosOverTransportEndorsing: A (one-way) transport binding is defined, with a KerberosToken required as an EndorsingSupportingToken. 
    • testKerberosOverAsymmetricEndorsing: An asymmetric binding is used, where a KerberosToken is required as an EndorsingSupportingToken.
    • testKerberosOverSymmetricProtection: A symmetric binding is used, where a KerberosToken is specified as a ProtectionToken of the binding.
    • testKerberosOverSymmetricDerivedProtection: The same as the previous test-case, except that any secret keys that are used must be derived.
    The first two test-cases use an EndorsingSupportingToken, which means that the secret key associated with the KerberosToken is used to sign (endorse) some message part (the timestamp for the Transport binding). This illustrates proof-of-possession. For the latter two test-cases, the KerberosToken is defined as a ProtectionToken, meaning that the secret key is used to sign/encrypt the request (e.g. instead of using an X.509 Token to encrypt a session key).

    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 "java.security.auth.login.config". The client (alice) uses the following login module:
    alice {
        com.sun.security.auth.module.Krb5LoginModule required
        refreshKrb5Config=true useKeyTab=true keyTab="/etc/alice.keytab"
        principal="alice";
    };and the service endpoint (bob) uses:
    bob {
        com.sun.security.auth.module.Krb5LoginModule required
        refreshKrb5Config=true useKeyTab=true storeKey=true
        keyTab="/etc/bob.keytab" principal="bob/service.ws.apache.org";
    }; 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 ...>
        <jaxws:properties>      
            <entry key="ws-security.bst.validator" value-ref="kerberosValidator"/>
        </jaxws:properties>
    </jaxws:endpoint> "kerberosValidator" is a KerberosTokenValidator instance given above. It requires a "contextName" property, which corresponds to the JAAS context name, as well as an optional "serviceName" property, and an optional "kerberosTokenDecoder" property to use to obtain a secret key. 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"
           createdFromAPI="true">
           <jaxws:properties>
               <entry key="ws-security.kerberos.client">
                   <bean class="org.apache.cxf.ws.security.kerberos.KerberosClient">
                       <constructor-arg ref="cxf"/>
                       <property name="contextName" value="alice"/>
                       <property name="serviceName" value="bob@service.ws.apache.org"/>
                   </bean>           
               </entry>
           </jaxws:properties>
    </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

    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="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:di="http://www.example.org/schema/DoubleIt" xmlns:tns="http://www.example.org/contract/DoubleIt" targetNamespace="http://www.example.org/contract/DoubleIt" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:fi="http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service" xmlns:tcp="http://java.sun.com/xml/ns/wsit/2006/09/policy/soaptcp/service" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sc="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy"> <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/schema/DoubleIt"> <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="http://schemas.xmlsoap.org/soap/http" /> <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="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <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 DoubleItService.java 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="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="mainclientconfig" > <import location="DoubleIt.xml" namespace="http://www.example.org/contract/DoubleIt"/> </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="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:di="http://www.example.org/schema/DoubleIt" xmlns:tns="http://www.example.org/contract/DoubleIt" targetNamespace="http://www.example.org/contract/DoubleIt" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:fi="http://java.sun.com/xml/ns/wsit/2006/09/policy/fastinfoset/service" xmlns:tcp="http://java.sun.com/xml/ns/wsit/2006/09/policy/soaptcp/service" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:sc="http://schemas.sun.com/2006/03/wss/server" xmlns:wspp="http://java.sun.com/xml/ns/wsit/policy" xmlns:sc1="http://schemas.sun.com/2006/03/wss/client"> <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/schema/DoubleIt"> <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="http://schemas.xmlsoap.org/soap/http" /> <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 java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; 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: "http://www.example.org/contract/DoubleIt/DoubleItPortType/DoubleItRequest" 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="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <S:Header> <To xmlns="http://www.w3.org/2005/08/addressing">https://localhost:8443/doubleit/services/doubleit</To> <Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1">http://www.example.org/contract/DoubleIt/DoubleItPortType/DoubleItRequest</Action> <ReplyTo xmlns="http://www.w3.org/2005/08/addressing"> <Address>http://www.w3.org/2005/08/addressing/anonymous</Address> </ReplyTo> <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:93e0c133-f54b-47ab-bcce-4d7dfdd71f53</MessageID> <wsse:Security S:mustUnderstand="1"> <wsu:Timestamp xmlns:ns15="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns14="http://www.w3.org/2003/05/soap-envelope" 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="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns14="http://www.w3.org/2003/05/soap-envelope" wsu:Id="uuid_7a42ed86-83c0-42ab-ab09-2c2cb6483297"> <wsse:Username>alice</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">clarinet</wsse:Password> </wsse:UsernameToken> </wsse:Security> </S:Header> <S:Body> <ns2:DoubleIt xmlns:ns2="http://www.example.org/schema/DoubleIt"> <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="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <S:Header> <To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To> <Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1">http://www.example.org/contract/DoubleIt/DoubleItPortType/DoubleItResponse</Action> <MessageID xmlns="http://www.w3.org/2005/08/addressing">uuid:d02f4957-1dfe-41b5-9640-eec9ee441b98</MessageID> <RelatesTo xmlns="http://www.w3.org/2005/08/addressing">uuid:93e0c133-f54b-47ab-bcce-4d7dfdd71f53</RelatesTo> <wsse:Security S:mustUnderstand="1"> <wsu:Timestamp xmlns:ns15="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns14="http://www.w3.org/2003/05/soap-envelope" 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="http://www.example.org/schema/DoubleIt"> <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.

    Notes

    • 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 "{http://schemas.sun.com/2006/03/wss/server}ValidatorConfiguration" was evaluated as "UNSUPPORTED". Oct 16, 2011 8:19:07 PM [com.sun.xml.ws.policy.EffectiveAlternativeSelector] 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 DoubleItService.java 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)
    Categories:

    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" />
        </util:map>

    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>
       
        <util:map id="aliceClaims">
            <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
                value="Alice" />
            <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
                value="Smith" />
            <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
                value="alice@mycompany.org" />
            <entry key="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role"
                value="user" />
               
        </util:map>


    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.
        <properties>
          <cxf.version>2.5.0-SNAPSHOT</cxf.version>

       </properties>
       <dependencies>        <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-transports-http</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-frontend-jaxws</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-ws-policy</artifactId>
                <version>${cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf.services.sts</groupId>
                <artifactId>cxf-services-sts-core</artifactId>
                <version>${cxf.version}</version>
            </dependency>
       </dependencies>  


    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"
                   keystoreFile="tomcatKeystore.jks"
                   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">
          <wsp:ExactlyOne>
             <wsp:All>
                <wsap10:UsingAddressing/>
                <sp:TransportBinding
                   xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                      <sp:TransportToken>
                         <wsp:Policy>
                            <sp:HttpsToken RequireClientCertificate="false"/>
                         </wsp:Policy>
                      </sp:TransportToken>
                      <sp:AlgorithmSuite>
                         <wsp:Policy>
                            <sp:TripleDesRsa15 />
                         </wsp:Policy>
                      </sp:AlgorithmSuite>
                      <sp:Layout>
                         <wsp:Policy>
                            <sp:Lax />
                         </wsp:Policy>
                      </sp:Layout>
                      <sp:IncludeTimestamp />
                   </wsp:Policy>
                </sp:TransportBinding>
                <sp:SignedSupportingTokens
                   xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                      <sp:UsernameToken
                         sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient">
                         <wsp:Policy>
                            <sp:WssUsernameToken10 />
                         </wsp:Policy>
                      </sp:UsernameToken>
                   </wsp:Policy>
                </sp:SignedSupportingTokens>
                <sp:Wss11
                   xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                      <sp:MustSupportRefKeyIdentifier />
                      <sp:MustSupportRefIssuerSerial />
                      <sp:MustSupportRefThumbprint />
                      <sp:MustSupportRefEncryptedKey />
                   </wsp:Policy>
                </sp:Wss11>
                <sp:Trust13
                   xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702">
                   <wsp:Policy>
                      <sp:MustSupportIssuedTokens />
                      <sp:RequireClientEntropy />
                      <sp:RequireServerEntropy />
                   </wsp:Policy>
                </sp:Trust13>
             </wsp:All>
          </wsp:ExactlyOne>
       </wsp:Policy>


    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"
    class="org.apache.cxf.sts.operation.TokenIssueOperation">
        <property name="tokenProviders" ref="transportTokenProviders"/>
        <property name="services" ref="transportService"/>
        <property name="stsProperties" ref="transportSTSProperties"/>
        <property name="claimsManager" ref="claimsManager"/>
    </bean>

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

    <util:list id="attributeStatementProvidersList">
        <ref bean="claimsAttributeProvider"/>
    </util:list>
       
    <bean id="claimsAttributeProvider"
            class="org.apache.cxf.sts.claims.ClaimsAttributeStatementProvider">
    </bean>

    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"
            class="org.talend.security.sts.UsernamePasswordCallbackHandler">
            <property name="passwords" ref="passwords" />
        </bean>
        <jaxws:endpoint id="transportSTS1"
            implementor="#transportSTSProviderBean"
            address="/STSService"
            wsdlLocation="/WEB-INF/wsdl/ws-trust-1.4-service.wsdl"
            xmlns:ns1="http://docs.oasis-open.org/ws-sx/ws-trust/200512/"
            serviceName="ns1:SecurityTokenService"
            endpointName="ns1:TransportUT_Port">
            <jaxws:properties>
                <entry key="ws-security.callback-handler" value-ref="upCallBackHandler"/>
            </jaxws:properties>
        </jaxws:endpoint>

    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"
            class="org.apache.cxf.sts.claims.ClaimsManager">
            <property name="claimHandlers" ref="claimHandlerList" />
        </bean>
       
        <util:list id="claimHandlerList">
            <ref bean="fileClaimsHandler"/>
        </util:list>
       
        <bean id="fileClaimsHandler"
            class="org.talend.security.sts.FileClaimsHandler">
           
            <property name="userClaims" ref="userClaims" />
        </bean>
    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>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>tomcat-maven-plugin</artifactId>
              <version>1.1</version>
              <configuration>
                   <server>myTomcat</server>
                   <url>http://localhost:9080/manager/text</url>
                   <path>/${project.build.finalName}</path>
              </configuration>
          </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:
        <url>http://localhost:9080/manager</url>


    6. Test the STS with SoapUI

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

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
       <soap:Header>
          <wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
             <wsse:UsernameToken wsu:Id="UsernameToken-1">
                <wsse:Username>alice</wsse:Username>
                <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">ecila</wsse:Password>
             </wsse:UsernameToken>
          </wsse:Security>
       </soap:Header>
       <soap:Body>
          <wst:RequestSecurityToken xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
             <wst:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</wst:TokenType>
             <wst:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</wst:KeyType>
             <wst:Claims Dialect="http://schemas.xmlsoap.org/ws/2005/05/identity" xmlns:ic="http://schemas.xmlsoap.org/ws/2005/05/identity">
                <ic:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"/>
                <ic:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"/>
                <ic:ClaimType Uri="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"/>
             </wst:Claims>
             <wst:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</wst:RequestType>
             <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
                <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                   <wsa:Address>https://localhost:8081/doubleit/services/doubleittransportsaml1claims</wsa:Address>
                </wsa:EndpointReference>
             </wsp:AppliesTo>
          </wst:RequestSecurityToken>
       </soap:Body>
    </soap:Envelope>



    and this the expected response (called RSTR):

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
       <soap:Header/>
       <soap:Body>
          <RequestSecurityTokenResponseCollection xmlns="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:ns4="http://www.w3.org/2005/08/addressing" xmlns:ns5="http://docs.oasis-open.org/ws-sx/ws-trust/200802">
             <RequestSecurityTokenResponse>
                <TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</TokenType>
                <RequestedSecurityToken>
                   <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="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
                      <saml2:Issuer>DoubleItSTSIssuer</saml2:Issuer>
                      <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
                         <ds:SignedInfo>
                            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                            <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
                            <ds:Reference URI="#_ACF774CE2C8F387D9413183197088603">
                               <ds:Transforms>
                                  <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
                                  <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
                                     <ec:InclusiveNamespaces PrefixList="xs" xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"/>
                                  </ds:Transform>
                               </ds:Transforms>
                               <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
                               <ds:DigestValue>YIHAnHYol0pOs1Mc4MWhgwTP540=</ds:DigestValue>
                            </ds:Reference>
                         </ds:SignedInfo>
                         <ds:SignatureValue>Mb3WfLefs0KziHe7NjhLUBsgfD2spr8M3HpqqhpO+yzIqMrw9eY1r7nFIh3nWeDOHY4odPBa0w06XDpzPGSzdmm9k/Ay+S6trtkgS/Hoi3sL8CGAmAHEPWSO4+td6MNrucdVhG9P+do6JflXDOppDroGh/YjvxpdosM55G2TbL0=</ds:SignatureValue>
                         <ds:KeyInfo>
                            <ds:X509Data>REMOVED</ds:X509Certificate>
                            </ds:X509Data>
                         </ds:KeyInfo>
                      </ds:Signature>
                      <saml2:Subject>
                         <saml2:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified" NameQualifier="http://cxf.apache.org/sts">alice</saml2:NameID>
                         <saml2:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"/>
                      </saml2:Subject>
                      <saml2:Conditions NotBefore="2011-10-11T07:55:08.860Z" NotOnOrAfter="2011-10-11T08:00:08.860Z">
                         <saml2:AudienceRestriction>
                            <saml2:Audience>https://localhost:8081/doubleit/services/doubleittransportsaml1claims</saml2:Audience>
                         </saml2:AudienceRestriction>
                      </saml2:Conditions>
                      <saml2:AttributeStatement>
                         <saml2:Attribute Name="givenname" NameFormat="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                            <saml2:AttributeValue xsi:type="xs:string">Alice</saml2:AttributeValue>
                         </saml2:Attribute>
                         <saml2:Attribute Name="surname" NameFormat="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                            <saml2:AttributeValue xsi:type="xs:string">Smith</saml2:AttributeValue>
                         </saml2:Attribute>
                         <saml2:Attribute Name="emailaddress" NameFormat="http://schemas.xmlsoap.org/ws/2005/05/identity/claims">
                            <saml2:AttributeValue xsi:type="xs:string">alice@mycompany.org</saml2:AttributeValue>
                         </saml2:Attribute>
                      </saml2:AttributeStatement>
                   </saml2:Assertion>
                </RequestedSecurityToken>
                <RequestedAttachedReference>
                   <ns3:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                      <ns3:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">#_ACF774CE2C8F387D9413183197088603</ns3:KeyIdentifier>
                   </ns3:SecurityTokenReference>
                </RequestedAttachedReference>
                <RequestedUnattachedReference>
                   <ns3:SecurityTokenReference wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd">
                      <ns3:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_ACF774CE2C8F387D9413183197088603</ns3:KeyIdentifier>
                   </ns3:SecurityTokenReference>
                </RequestedUnattachedReference>
                <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
                   <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
                      <wsa:Address>https://localhost:8081/doubleit/services/doubleittransportsaml1claims</wsa:Address>
                   </wsa:EndpointReference>
                </wsp:AppliesTo>
                <Lifetime>
                   <ns2:Created>2011-10-11T07:55:08.872Z</ns2:Created>
                   <ns2:Expires>2011-10-11T08:00:08.872Z</ns2:Expires>
                </Lifetime>
             </RequestSecurityTokenResponse>
          </RequestSecurityTokenResponseCollection>
       </soap:Body>
    </soap:Envelope>



    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 ws.apache.org. The entire entry should look like:
      WS.APACHE.ORG = {
                   kdc = localhost
                   admin_server = localhost
                   default_domain = ws.apache.org
      }
    • Under the "[domain_realm]" section, add the following:     
    ws.apache.org = WS.APACHE.ORG   
    .ws.apache.org = WS.APACHE.ORG
    • Finally, add a logging section:
    [logging]

            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/service.ws.apache.org"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/service.ws.apache.orgTo 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 https://svn.apache.org/repos/asf/cxf/trunk/systests/ws-security/Open KerberosTokenTest.java 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 -Djava.security.auth.login.config=src/test/resources/kerberos.jaas

    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">
        <wsp:Policy>
            <sp:WssGssKerberosV5ApReqToken11/>
        </wsp:Policy>
    </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 "java.security.auth.login.config". The client (alice) uses the following login module:
    alice {
        com.sun.security.auth.module.Krb5LoginModule required 
        refreshKrb5Config=true useKeyTab=true keyTab="/etc/alice.keytab"  
        principal="alice";
    };and the service endpoint (bob) uses:
    bob {
        com.sun.security.auth.module.Krb5LoginModule required
        refreshKrb5Config=true useKeyTab=true storeKey=true
        keyTab="/etc/bob.keytab" principal="bob/service.ws.apache.org";
    }; 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 ...>   
        <jaxws:properties>      
            <entry key="ws-security.bst.validator" value-ref="kerberosValidator"/>
        </jaxws:properties>
    </jaxws:endpoint> "kerberosValidator" is defined as:
    <bean id="kerberosValidator"
        class="org.apache.ws.security.validate.KerberosTokenValidator">
        <property name="contextName" value="bob"/>
        <property name="serviceName" value="bob@service.ws.apache.org"/>
    </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"
           createdFromAPI="true">
           <jaxws:properties>
               <entry key="ws-security.kerberos.client">
                   <bean class="org.apache.cxf.ws.security.kerberos.KerberosClient">
                       <constructor-arg ref="cxf"/>
                       <property name="contextName" value="alice"/>
                       <property name="serviceName" value="bob@service.ws.apache.org"/>
                   </bean>           
               </entry>
           </jaxws:properties>
    </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
    Hello,
    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: http://tomcat.apache.org/maven-plugin-2.0-SNAPSHOT/snapshot-test.html.

    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: https://issues.apache.org/jira/browse/MTOMCAT

    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:

    Categories:

    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 http://www.talend.com/webinar/. 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="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.gmazza.blog.basic-doubleit</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>/${project.build.finalName}</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>

        ...as 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 stsKeystore.properties configuration file:

        stsKeystore.properties

        org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=stsspass org.apache.ws.security.crypto.merlin.keystore.alias=mystskey org.apache.ws.security.crypto.merlin.keystore.file=stsstore.jks
    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:

      DoubleItSTSService.wsdl:

      <?xml version="1.0" encoding="UTF-8"?> <wsdl:definitions targetNamespace="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" xmlns:tns="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" xmlns:wstrust="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsap10="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wst="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata"> > <wsdl:types> <xs:schema elementFormDefault="qualified" targetNamespace='http://docs.oasis-open.org/ws-sx/ws-trust/200512'> <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="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Cancel" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/CancelFinal" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="Issue"> <wsdl:input wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTRC/IssueFinal" message="tns:RequestSecurityTokenResponseCollectionMsg" /> </wsdl:operation> <wsdl:operation name="Renew"> <wsdl:input wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Renew" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/RenewFinal" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="Validate"> <wsdl:input wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Validate" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/ValidateFinal" message="tns:RequestSecurityTokenResponseMsg" /> </wsdl:operation> <wsdl:operation name="KeyExchangeToken"> <wsdl:input wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/KET" message="tns:RequestSecurityTokenMsg" /> <wsdl:output wsam:Action="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RSTR/KETFinal" 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="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="Issue"> <soap:operation soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue" /> <wsdl:input> <wsp:PolicyReference URI="#Input_policy" /> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <wsp:PolicyReference URI="#Output_policy" /> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> <wsdl:operation name="Validate"> <soap:operation soapAction="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Validate" /> <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="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Cancel" /> <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="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Renew" /> <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="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/KeyExchangeToken" /> <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="http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/RequestCollection" /> <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="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <wsp:Policy> <sp:InitiatorToken> <wsp:Policy> <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <wsp:Policy> <sp:WssX509V3Token10 /> </wsp:Policy> </sp:X509Token> </wsp:Policy> </sp:InitiatorToken> <sp:RecipientToken> <wsp:Policy> <sp:X509Token sp:IncludeToken="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/Never"> <wsp:Policy> <sp:WssX509V3Token10 /> <sp:RequireIssuerSerialReference /> </wsp:Policy> </sp:X509Token> </wsp:Policy> </sp:RecipientToken> <sp: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="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <wsp:Policy> <sp:MustSupportRefKeyIdentifier /> <sp:MustSupportRefIssuerSerial /> <sp:MustSupportRefThumbprint /> <sp:MustSupportRefEncryptedKey /> </wsp:Policy> </sp:Wss11> <sp:Trust13 xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <wsp:Policy> <sp:MustSupportIssuedTokens /> <sp:RequireClientEntropy /> <sp:RequireServerEntropy /> </wsp:Policy> </sp:Trust13> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="Input_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <sp:Body /> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" /> </sp:SignedParts> <sp:EncryptedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <sp:Body /> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsp:Policy wsu:Id="Output_policy"> <wsp:ExactlyOne> <wsp:All> <sp:SignedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <sp:Body /> <sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing" /> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing" /> </sp:SignedParts> <sp:EncryptedParts xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702"> <sp:Body /> </sp:EncryptedParts> </wsp:All> </wsp:ExactlyOne> </wsp:Policy> <wsdl: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:

      cxf-servlet.xml:

      <beans xmlns="http://www.springframework.org/schema/beans" xmlns:cxf="http://cxf.apache.org/core" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:test="http://apache.org/hello_world_soap_http" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"> <import resource="classpath:META-INF/cxf/cxf.xml"/> <cxf:bus> <cxf:features> <cxf:logging /> </cxf:features> </cxf:bus> <bean id="x509STSProviderBean" class="org.apache.cxf.ws.security.sts.provider.SecurityTokenServiceProvider"> <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="stsKeystore.properties" /> <property name="signatureUsername" value="mystskey" /> <property name="callbackHandlerClass" value="sts.PasswordCallbackHandler" /> <property name="encryptionPropertiesFile" value="stsKeystore.properties" /> <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="http://docs.oasis-open.org/ws-sx/ws-trust/200512/" serviceName="ns1:SecurityTokenService" endpointName="ns1:X509_Port"> <jaxws:properties> <entry key="ws-security.callback-handler" value="sts.PasswordCallbackHandler" /> <entry key="ws-security.signature.properties" value="stsKeystore.properties" /> <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.xml:

      <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"> <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="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:di="http://www.example.org/schema/DoubleIt" xmlns:tns="http://www.example.org/contract/DoubleIt" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:sp="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702" xmlns:t="http://docs.oasis-open.org/ws-sx/ws-trust/200512" xmlns:wsaw="http://www.w3.org/2005/08/addressing" xmlns:wsx="http://schemas.xmlsoap.org/ws/2004/09/mex" targetNamespace="http://www.example.org/contract/DoubleIt" > <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/schema/DoubleIt"> <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="http://schemas.xmlsoap.org/soap/http" /> <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="http://docs.oasis-open.org/ws-sx/ws-securitypolicy/200702/IncludeToken/AlwaysToRecipient"> <sp:RequestSecurityTokenTemplate> <t:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1</t:TokenType> <t:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/SymmetricKey</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="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="AckRequested" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="SequenceAcknowledgement" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="Sequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="CreateSequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <!--CXF uses by default for the docs/200702 ones: Namespace="http://schemas.xmlsoap.org/ws/2005/02/rm"/--> </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="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/> <sp:Header Name="AckRequested" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="SequenceAcknowledgement" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="Sequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> <sp:Header Name="CreateSequence" Namespace="http://docs.oasis-open.org/ws-rx/wsrm/200702"/> </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:

        ClientCallbackHandler.java:

        package client; import java.io.IOException; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.ws.security.WSPasswordCallback; public class ClientCallbackHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof WSPasswordCallback) { // 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 clientKeystore.properties file:

        clientKeystore.properties:

        org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=cspass org.apache.ws.security.crypto.merlin.keystore.alias=myclientkey org.apache.ws.security.crypto.merlin.file=clientstore.jks
      • 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.

        cxf.xml:

        <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:client name="{http://www.example.org/contract/DoubleIt}DoubleItPort" createdFromAPI="true"> <jaxws:properties> <entry key="ws-security.sts.client"> <bean class="org.apache.cxf.ws.security.trust.STSClient"> <constructor-arg ref="cxf"/> <property name="wsdlLocation" value="DoubleItSTSService.wsdl"/> <property name="serviceName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}DoubleItSTSService"/> <property name="endpointName" value="{http://docs.oasis-open.org/ws-sx/ws-trust/200512/}DoubleItSTSPort"/> <property name="properties"> <map> <entry key="ws-security.signature.username" value="myclientkey"/> <entry key="ws-security.callback-handler" value="client.ClientCallbackHandler"/> <entry key="ws-security.signature.properties" value="clientKeystore.properties"/> <entry key="ws-security.encryption.properties" value="clientKeystore.properties"/> <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.

    Categories:

    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 : http://people.apache.org/~olamy/core/maven-3-r1178324/

    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 !
    --
    Olivier

    [1] http://hc.apache.org/httpcomponents-client-ga/index.html
    [2] http://repo1.maven.org/maven2/org/apache/maven/wagon/wagon-http/2.0/wagon-http-2.0-shaded.jar


    Categories: Olivier Lamy

    Pages

    Subscribe to Talend Community Coders aggregator