Colm O hEigeartaigh

Subscribe to Colm O hEigeartaigh feed
Colm O hEigeartaighhttp://www.blogger.com/profile/10711987281965801793noreply@blogger.comBlogger249125
Updated: 12 hours 48 min ago

Custom token validation in Apache CXF 2.4

Tue, 06/28/2011 - 15:37
A previous blog post has covered validators in Apache WSS4J 1.6, why they were introduced, what default implementations ship with WSS4J, etc. It ends with a paragraph on how to use a custom Validator implementation with Apache CXF 2.4. This post expands further on this topic.

1) Use-cases for custom Token Validation

Let's consider first of all the use-cases for specifying a custom Validator implementation in CXF. When a security header is being processed by WSS4J, it delegates each security token to a Processor implementation, depending on the QName of the token. In WSS4J 1.6, Processors do not do any validation of extracted credentials from a token, they merely process it, make sure it meets basic requirements, etc. Validation is delegated to a Validator interface which is associated with that Processor implementation.

However, there are many possible use-cases where a user may wish to replace or remove or extend the default validation behaviour associated with a particular security token. Some examples include:
  1. Validating a UsernameToken, where the CallbackHandler implementation does not have access to the password.
  2. Validating a BinarySecurityToken of some custom type.
  3. Validating the attributes of a received SAML Assertion
  4. Validating a Timestamp in a more tolerant manner than the default.
  5. Dispatching a received security token to a third-party security service for validation/authentication.
2) Configuring custom Validators in CXF
    The CXF SecurityConstants class (javadoc) defines some configuration items to override the default validators used to validate a received security token. The values associated with each configuration option must correspond to an implementation of the Validator interface. The configuration tags are:
    1. "ws-security.ut.validator" - Override UsernameToken validation.
    2. "ws-security.saml1.validator" - Override SAML1 token validation.
    3. "ws-security.saml2.validator" - Override SAML2 token validation.
    4. "ws-security.timestamp.validator" - Override Timestamp validation.
    5. "ws-security.signature.validator" - Override trust verification on a signature
    6. "ws-security.bst.validator" - Override BinarySecurityToken validation.
    To disable the validation of a particular token, specify the NoOpValidator as the value of the configuration tag corresponding to that token.

    3) Using Validators with WS-Trust

    To see the power and flexibility of the approach of separating processing from validation, consider the STSTokenValidator that ships with CXF 2.4. This validator implementation has the ability to dispatch a received BinarySecurityToken, UsernameToken, or SAML Assertion to an STS (Security Token Service) for validation via WS-Trust. On invocation, it delegates the credential to another validator (STSSamlAssertionValidator). This validator essentially catches an exception caused by a signature validation failure of the SAML Assertion and sets a flag. Only if signature validation is unsuccessful does the STSTokenValidator dispatch the token to the STS for validation.

    An example of how to configure the STSTokenValidator to validate a SAML1 Assertion against an STS in spring is as follows:

    <jaxws:endpoint ...>
      <jaxws:properties>
        <entry key="ws-security.saml1.validator">
          <bean class="org.apache.cxf.ws.security.trust.STSTokenValidator"/>
        </entry>
        <entry key="ws-security.sts.client">
          <bean class="org.apache.cxf.ws.security.trust.STSClient">
            <constructor-arg ref="cxf"/>
            <property name="wsdlLocation" value="..."/>
            <property name="serviceName" value=".../>
            <property name="endpointName" value="..."/>
             ...       
           </bean>           
         </entry>
       </jaxws:properties>
     </jaxws:endpoint>

    The STSTokenValidator also has the ability to obtain a transformed token from the STS and store it in the credential, where it is available as part of the WSSecurityEngineResult under the TAG_TRANSFORMED_TOKEN tag.
    Categories: Colm O hEigeartaigh

    WS-SecurityPolicy/SAML sample in Talend Service Factory 2.4.0

    Fri, 06/10/2011 - 23:05
    In this post I will walk through the WS-SecurityPolicy sample that ships with Talend Service Factory 2.4.0. This sample shows how to secure a web service provider using both a UsernameToken and a SAML Assertion. For this post I will concentrate exclusively on the SAML case.

    1) Download the artifacts

    Go here and download Talend Service Factory 2.4.0. When this is done, go here and download the Talend Service Factory 2.4.0 examples (registration required). Extract the examples into the Talend Service Factory (TSF) install directory ($TSF_HOME). Finally, this sample requires that unlimited strength security policies be installed in the JDK.

    2) Build and run the sample

    Go to $TSF_HOME/examples/jaxws-ws-secpol and start with the README.txt. Run "mvn eclipse:eclipse" to generate eclipse projects, and "mvn install" to build and install the various modules. There are two options to run the sample.

    2.1) Run the sample using maven

    To start the service go to the service folder, and run "mvn exec:java". To run the test then go to the client folder and also run "mvn exec:java".

    2.2) Run the sample in Karaf

    To deploy the service and run the client in an OSGi environment, we can take advantage of the Karaf distribution that ships with TSF. Go to $TSF_HOME/container/bin and run the "karaf" binary. Install the three bundles in Karaf with:
    • install mvn:com.talend.sf.examples.jaxws-ws-secpol/ws-secpol-common/1.0
    • install mvn:com.talend.sf.examples.jaxws-ws-secpol/ws-secpol-server/1.0
    • install mvn:com.talend.sf.examples.jaxws-ws-secpol/ws-secpol-client/1.0
    Each of these commands will print out a bundle id. Run the sample by invoking "start <id>" for each of the three bundle ids in turn.

    3) The Service Provider

    3.1) The Security Policy

    The Service endpoint is secured via the following security policy fragment, which is defined in the WSDL ("ws-secpol-wsdl/greeter.wsdl" in the common folder):

    <wsp:All>
      <sp:AsymmetricBinding xmlns:sp=".../ws-securitypolicy/200702">
        <wsp:Policy>
          <sp:InitiatorToken>
            <wsp:Policy>
              <sp:X509Token sp:IncludeToken=".../AlwaysToRecipient">
                <wsp:Policy>
                  <sp:RequireThumbprintReference />
                  <sp:WssX509V3Token10 />
                </wsp:Policy>
              </sp:X509Token>
            </wsp:Policy>
          </sp:InitiatorToken>
          <sp:RecipientToken>
            <wsp:Policy>
              <sp:X509Token sp:IncludeToken=".../Never">
                <wsp:Policy>
                  <sp:RequireThumbprintReference />
                  <sp:WssX509V3Token10 />
                </wsp:Policy>
              </sp:X509Token>
            </wsp:Policy>
          </sp:RecipientToken>
          ...
        </wsp:Policy>
      </sp:AsymmetricBinding>
      ...
      <sp:SignedSupportingTokens xmlns:sp=".../ws-securitypolicy/200702">
        <wsp:Policy>
          <sp:SamlToken sp:IncludeToken=".../AlwaysToRecipient">
            <wsp:Policy>
              <sp:WssSamlV20Token11/>
            </wsp:Policy>
          </sp:SamlToken>
        </wsp:Policy>
      </sp:SignedSupportingTokens>
    </wsp:All>

    This Security Policy defines that the Asymmetric Binding is to be used in communication with the service provider, i.e. that the client must sign the request using its private key, and include the corresponding X509 Certificate in the security header of the request, and encrypt the request using the public key of the service provider. Authentication is performed on the basis of trust verification of the client's certificate, as the client illustrates proof-of-possession by signing some part of the request.

    In addition to the Asymmetric Binding, the policy requires that a SAML 2.0 Assertion must be included in the service request, and it must be signed by the signature defined by the Asymmetric Binding policy. The (policy-driven) ability to add a SAML Assertion to a SOAP Request is new to Apache CXF 2.4.

    Finally, the WSDL defines input and output policies (not included here), which specify that the SOAP Body must be signed and encrypted, and that all of the addressing headers must be signed if present.

    3.2) The configuration

    The standalone (maven-driven) case is configured entirely in code. The various security configuration items are added as properties to the JAX-WS Endpoint object. The same security configuration items are also used for the case of deploying the service provider in Karaf, except that it is all driven through spring, e.g.:

    <jaxws:server id="SAMLGreeter" xmlns:ns1="..."
      endpointName="ns1:SAMLGreeterPort"
      serviceClass="demo.secure_greeter.server.GreeterImpl">
      <jaxws:properties>
        <entry key="ws-security.callback-handler" value="..."/>
        <entry key="ws-security.encryption.properties" value="..."/>
        <entry key="ws-security.signature.properties" value="..."/>
        <entry key="ws-security.saml2.validator" value="..."/>
      </jaxws:properties>
    </jaxws:server>

    Four security-related configuration options are used for the service provider. "ws-security.callback-handler" points to a CallbackHandler implementation that is used to supply a password for extracting a private key from a keystore to decrypt the request and sign the response. "ws-security.encryption.properties" refers to a properties file which contains configuration options for loading the keystore used for encryption. Similarly, "ws-security.signature.properties" refers to a properties file for signature creation (and decryption).

    "ws-security.saml2.validator" is a configuration tag new to CXF 2.4, and refers to an instance of the WSS4J Validator interface. The Validator interface is used in WSS4J to validate received security tokens. In this case, we are extending the default SAML2 Token Validation with a custom Validator. This Validator does some additional verification on the received token, namely checking who the issuer is, checking that the confirmation method is "sender-vouches", and checking that the Assertion contains an AttributeStatement, with an Attribute "attribute-role" containing a value "authenticated-client".

    All of these configuration tags are defined in the SecurityConstants class in CXF.

    4) The client

    When the client wants to invoke on the service provider, it parses the security policy described above in the WSDL. As with the service provider, the client standalone case is configured entirely in code. For the case of deploying the client in Karaf, it is configured in spring as follows: 

    <jaxws:client id="samlgreeter" wsdlLocation="..." serviceClass="..."
      xmlns:ns1="" serviceName="ns1:SecureGreeterService"
      endpointName="ns1:SAMLGreeterPort">
      <jaxws:properties>
        <entry key="ws-security.signature.username" value="..."/>
        <entry key="ws-security.encryption.username" value="..."/>
        <entry key="ws-security.callback-handler"><bean class="..."/></entry>
        <entry key="ws-security.signature.properties" value="..."/>
        <entry key="ws-security.encryption.properties" value="..."/>
        <entry key="ws-security.saml-callback-handler" value="..."/>
      </jaxws:properties>
    </jaxws:client>

    "ws-security.callback-handler", "ws-security.signature.properties" and "ws-security.encryption.properties" have been covered in the section on configuring the service provider. "ws-security.signature.username" refers to the keystore alias of the private key to use to sign the request, and "ws-security.encryption.username" refers to the keystore alias to use to encrypt the request.

    "ws-security.saml-callback-handler" is a configuration tag new to CXF 2.4, and refers to a CallbackHandler which will supply WSS4J with the information to create a SAML Assertion. This sample ships with a CallbackHandler that creates a simple SAML 2.0 Assertion with a subject confirmation method of "sender-vouches". It adds an Attribute to the Assertion that conveys to the Web Service Provider that the client has authenticated an external user in some way (not shown as part of this sample), and has assigned the attribute role of "authenticated-client" to the external user. The assertion that will be generated from this CallbackHandler instance will be signed by the client, as per the policy definition ("SignedSupportingTokens").

    5) The Client Request

    The security header of the client request contains a BinarySecurityToken which contains the certificate to use to verify the signature. It also contains a Timestamp, an EncryptedKey which is used to encrypt the SOAP Body, a SAML2 Assertion, and a Signature which signs the Timestamp, Assertion and encrypted SOAP Body. The Assertion looks like this:

    <saml2:Assertion xmlns:saml2="..." xmlns:xsi="..." ID="..." IssueInstant="..."
      Version="2.0" xsi:type="saml2:AssertionType">
     <saml2:Issuer>...</saml2:Issuer>
     <saml2:Subject>
       <saml2:NameID Format=...:unspecified">uid=auth_client</saml2:NameID>
       <saml2:SubjectConfirmation Method="...:sender-vouches">
         <saml2:SubjectConfirmationData/>
       </saml2:SubjectConfirmation>
     </saml2:Subject>
     <saml2:Conditions NotBefore="..." NotOnOrAfter="..."/>
     <saml2:AttributeStatement>
       <saml2:Attribute FriendlyName="attribute-role" NameFormat="...">
         <saml2:AttributeValue xsi:type="xs:string">
           authenticated-client
         </saml2:AttributeValue>
       </saml2:Attribute>
     </saml2:AttributeStatement>
    </saml2:Assertion>

    The service provider processes the received security header as follows:
    1. It checks that the Timestamp is valid
    2. It uses its private key to decrypt the EncryptedKey, and then uses the decrypted key to decrypt the SOAP Body.
    3. It verifies that the Assertion is valid, and passes the Assertion to the custom Validator defined above to validate the contents of the Assertion.
    4. It verifies that the certificate defined in the BinarySecurityToken can validate the signature, verifies trust in the certificate, and checks that each of the References of the signature produce the correct digest.
    At this point security processing is complete, and the service provider constructs a secured response to the client.
    Categories: Colm O hEigeartaigh

    WSS4J 1.6.1 released

    Wed, 06/08/2011 - 15:11
    Apache WSS4J 1.6.1 has been released. The distribution can be downloaded here, and the list of issues that have been fixed is here. There are a number of bug fixes to the new functionality introduced in the 1.6.0 release, including some fixes to the SAML Assertion creation code, and a fix to get WSS4J 1.6 working with the IBM JDK. A noteworthy new feature is support for CRLs, as documented by a previous blog post.

    In other news, my employer has published a short questionnaire to find out what topics users of open-source integration software are interested in learning about. So for example if you are interested in hearing more from me on enabling security in Apache CXF, navigate to the CXF part of the survey and select the appropriate checkbox for "WS-Security in Apache CXF".
    Categories: Colm O hEigeartaigh

    CRL support in WSS4J 1.6.1

    Mon, 05/30/2011 - 16:12
    Support for Certificate Revocation Lists (CRLs) has been a long sought feature in WSS4J, and will arrive in the imminent release of WSS4J 1.6.1. This will ensure that the certificate used to validate a signature is not revoked by the issuing Certificate Authority.

    Support for CRLs is covered by the task WSS-278. The default behaviour is that certificate revocation is not enabled for backwards compatibility reasons. Two parameters must be configured to enable certificate revocation. The first is that the WSHandlerConstants property "enableRevocation" must be set to "true", if WSS4J is being used in the context of WSHandler. If the handler architecture is not being used, then a new method has been added to the Crypto interface for signature trust validation which explicitly enables certificate revocation:
    • public boolean verifyTrust(X509Certificate[] certs, boolean enableRevocation) throws WSSecurityException;
    The previous verifyTrust(certs) method has been deprecated. Please bear in mind that any custom Crypto implementation must be updated with the new method, or else you will face a compilation error on upgrading to WSS4J 1.6.1.

    The second is that the Crypto instance that is used must be supplied with CRL information. This can be done in a number of different ways. The default Crypto instance that ships with WSS4J (Merlin), has a new configuration property:
    • org.apache.ws.security.crypto.merlin.x509crl.file: The location of an (X509) CRL file to be loaded via CertificateFactory.generateCRL(...).
    Merlin also has two new accessor methods to set/get a CertStore object to be used for CRL checking (i.e. setCRLCertStore(CertStore crlCertStore)), if you wish to supply CRL information programatically to the Crypto instance.

    Update: You can see a test for this feature here.
    Categories: Colm O hEigeartaigh

    Apache XML Security for Java 1.4.5 released

    Fri, 05/27/2011 - 15:53
    Apache XML Security for Java 1.4.5 has been released:
    The Apache Santuario team are pleased to announce the release of
    version 1.4.5 of the Apache XML Security for Java library. This
    release fixes a thread safety issue in the ResourceResolver, and a
    regression in signature generation for the Canonical XML 1.1
    algorithm, as well as a number of other bug fixes.

    Please see the release notes for more information:

    https://issues.apache.org/jira/browse/SANTUARIO/fixforversion/12315957

    You can download the library here:

    http://santuario.apache.org/download.html
    Categories: Colm O hEigeartaigh

    Talend ESB Standard Edition released

    Wed, 05/18/2011 - 19:36
    Last week the Talend ESB Standard Edition was released:
    A core component of the unified platform for data services, Talend ESB includes messaging, Web services, mediation and adapters in an open and standards-based offering used to integrate distributed systems across functional, enterprise and/or geographic boundaries. Powered by leading Apache open source integration projects Apache CXF, Apache Camel and Apache ActiveMQ, Talend ESB is a versatile and flexible ESB that allows organizations to address any integration challenge, from simple departmental projects to complex, heterogeneous IT environments.Of particular interest to readers of this blog might be the Security Token Service (STS) framework which ships as part of Talend ESB. More on this in a future blog post.

    To download Talend ESB Standard Edition go here. For more information, see the datasheet here.

    In other Talend-related news, Talend is now a sponsor of the Apache Software Foundation.
    Categories: Colm O hEigeartaigh

    WS-Trust sample in Talend Service Factory 2.4.0

    Wed, 05/11/2011 - 18:18
    In this post I will walk through the WS-Trust sample that ships with Talend Service Factory 2.4.0.

    1) Download the artifacts

    Go here and download Talend Service Factory 2.4.0. When this is done, go here and download the Talend Service Factory 2.4.0 examples (registration required). Extract the examples into the Talend Service Factory (TSF) install directory ($TSF_HOME).

    2) Build and run the sample

    Go to $TSF_HOME/examples/jaxws-ws-trust and start with the README.txt. Run "mvn eclipse:eclipse" to generate eclipse projects, and "mvn install" to build and install the various modules.

    Both the CXF service provider and Metro STS used in this sample are deployed in Tomcat. To see how to configure Maven to install/uninstall these artifacts in Tomcat follow the instructions here. Finally, you need to make sure that the path to the keystores is correct for the Metro STS - follow the instructions in the README.txt for this.

    Start Tomcat, and from the sts-war folder run "mvn install tomcat:deploy". Run the same command from the service-war folder to deploy the CXF service provider in Tomcat.

    Finally to run the test, go to the client folder and run "mvn install exec:exec". You also have the option of running the client in Karaf (follow the instructions in the README.txt).

    3) The sample

    Three service invocations take place as part of this sample. For simplicity, I'll just concentrate on the third one, which shows how a SAML2 Assertion is used in a WS-Trust scenario.

    3.1) The Service Provider

    We'll start with the Service Provider, as the client will use the security policies defined in the WSDL of the Service Provider to access the STS. The Service is spring-loaded via the following configuration:

    <jaxws:endpoint id="doubleitsaml2"
          implementor="service.DoubleItPortTypeImpl"
          address="/doubleitsaml2"
          endpointName="DoubleItPortSAML2"
          wsdlLocation="WEB-INF/wsdl/DoubleIt.wsdl">
           
          <jaxws:properties>
             <entry key="ws-security.callback-handler" value="..."/>
             <entry key="ws-security.signature.properties" value="..."/>
             <entry key="ws-security.is-bsp-compliant" value="false"/>
          </jaxws:properties>
    </jaxws:endpoint>

    Three properties are required for the endpoint. The CallbackHandler implementation is required to provider the password used to access the private key in the Keystore, which is in turn configured in the "ws-security.signature.properties" file. The "ws-security.is-bsp-compliant" configuration turns off Basic Security Profile 1.1 compliance enforcement. This is required as the Metro STS generates a non BSP-compliant SAML Assertion (try removing this line, redeploying the service provider in tomcat and see what happens when the test is re-run).

    The WSDL (DoubleIt.wsdl) contains the security policies for the service provider. It requires that the input and output SOAP Body elements must be signed and encrypted, and that all of the addressing headers must be signed in both directions. It also contains the following policy snippet:

    <sp:SymmetricBinding>
      <wsp:Policy>
        <sp:ProtectionToken>
          <wsp:Policy>
            <sp:IssuedToken sp:IncludeToken="...AlwaysToRecipient">
              <sp:RequestSecurityTokenTemplate>
                <t:TokenType>...#SAMLV2.0</t:TokenType>
                <t:KeyType>.../SymmetricKey</t:KeyType>
                <t:KeySize>256</t:KeySize>
              </sp:RequestSecurityTokenTemplate>
              ...
              <sp:Issuer>
                <wsaw:Address>http://.../DoubleItSTSServiceUT</wsaw:Address>
                <wsaw:Metadata>
                  ...
                </wsaw:Metadata>
              </sp:Issuer>
            </sp:IssuedToken>
          </wsp:Policy>
        </sp:ProtectionToken>
        ...
      </wsp:Policy>
    </sp:SymmetricBinding>

    This SecurityPolicy snippet defines that the communication with the service provider is secured via the SymmetricBinding, i.e. that it is secured via a secret key. The ProtectionToken policy describes how the secret key in turn is conveyed to the service provider in a secure way. In this example, it defines an IssuedToken policy, which is always sent to the recipient (service provider). Once the client sees this policy, it will know that it must contact a Security Token Service (STS) via the WS-Trust protocol to obtain a (issued) token that will convey the symmetric key to the service provider.

    The IssuedToken policy has a RequestSecurityTokenTemplate policy, which the client will copy verbatim when contacting the STS for a security token. It describes the token type that is required (a SAML2 Assertion), the KeyType conveyed in the Assertion (Symmetric Key), and the size of the symmetric key (256 bits). It also contains an Issuer policy which describes how the STS may be contacted via a wsa EndpointReferenceType.

    3.2) The Security Token Service (STS)

    The STS used in this sample is the Metro STS. The port is secured with the following security policy binding:

    <sp:AsymmetricBinding>
      <wsp:Policy>
         <sp:InitiatorToken>
           <wsp:Policy>
             <sp:X509Token sp:IncludeToken=".../AlwaysToRecipient">
               <wsp:Policy>
                 <sp:WssX509V3Token10 />
               </wsp:Policy>
             </sp:X509Token>
           </wsp:Policy>
           </sp:InitiatorToken>
         <sp:RecipientToken>
           <wsp:Policy>
             <sp:X509Token sp:IncludeToken=".../Never">
               <wsp:Policy>
                 <sp:WssX509V3Token10 />
                 <sp:RequireIssuerSerialReference />
               </wsp:Policy>
             </sp:X509Token>
           </wsp:Policy>
         </sp:RecipientToken>
          ...
      </wsp:Policy>
    </sp:AsymmetricBinding>

    This Security Policy defines that the Asymmetric Binding is to be used in communication with the STS, i.e. that the client must sign the request using its private key, and include the corresponding X509 Certificate in the security header of the request, and encrypt the request using the public key of the STS. Authentication is performed on the basis of trust verification of the client's certificate, as the client illustrates proof-of-possession by signing some part of the request.

    The WSDL of the STS also contains a "STSConfiguration" policy fragment, which defines that the issued key is encrypted, and lists the service provider endpoints, including the corresponding public keys.

    3.3) The client

    When the client wants to invoke on the service provider, it parses the security policy described above in the WSDL, and sees that it must first obtain an IssuedToken from a STS before it can construct the service request. The client is configured in spring as follows:

    <jaxws:client name="{...}DoubleItPortSAML2" 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="{...}DoubleItSTSService"/>
            <property name="endpointName" value="{...}IDoubleItSTS..Port"/>
            <property name="properties">
              <map>
                <entry key="ws-security.signature.username" value="..."/>
                <entry key="ws-security.callback-handler" value="..."/>
                <entry key="ws-security.signature.properties" value="..."/>
                <entry key="ws-security.encryption.properties" value="..."/>
                <entry key="ws-security.encryption.username" value="..."/>
              </map>
            </property>
          </bean>           
        </entry>
      </jaxws:properties>
    </jaxws:client>

    The STSClient bean contains the configuration required to contact the STS. The client parses the WSDL of the STS, and uses the supplied configuration parameters to construct a request that is secured by the Asymmetric Binding, as discussed above. This request is done via the WS-Trust protocol.

    3.4) The STS request

    In the SOAP Body of the request is the following information (decrypted):

    <wst:RequestSecurityToken>
      <wst:SecondaryParameters>
        <t:TokenType>...#SAMLV2.0</t:TokenType>
        <t:KeyType>.../SymmetricKey</t:KeyType>
        <t:KeySize>256</t:KeySize>
      </wst:SecondaryParameters>
      <wst:RequestType>.../Issue</wst:RequestType>
      <wsp:AppliesTo>
        <wsa:EndpointReference>
        ...
        </wsa:EndpointReference>
      </wsp:AppliesTo>
      ...
      <wst:Entropy>
        <wst:BinarySecret Type=".../Nonce">...</wst:BinarySecret>
      </wst:Entropy>
      <wst:ComputedKeyAlgorithm>.../CK/PSHA1</wst:ComputedKeyAlgorithm></wst:RequestSecurityToken>

    The SecondaryParameters element is copied verbatim from the RequestSecurityTokenTemplate defined in the policy of the service provider. The RequestType element defines an "Issue" URI. AppliesTo refers to the address of the service provider. Entropy contains some client-generated entropy (which the STS will combine with its own Entropy to form a symmetric key), using the ComputedKeyAlgorithm URI.

    3.5) The STS response

    The response from the STS contains the following (decrypted) SOAP Body. It contains the token type of the requested token, the token itself, different ways of referring to the requested token, some entropy that the client can use to recreate the symmetric key, the lifetime of the requested token, etc:

    <trust:RequestSecurityTokenResponseCollection>
      <trust:RequestSecurityTokenResponse>
        <trust:TokenType>...#SAMLV2.0</trust:TokenType>
        <trust:RequestedSecurityToken>
          <saml2:Assertion>
          ...
          </saml2:Assertion>
        </trust:RequestedSecurityToken>
        <trust:RequestedAttachedReference>...</trust:RequestedAttachedReference>
        <trust:RequestedUnattachedReference>
        ...
        </trust:RequestedUnattachedReference>
        <wsp:AppliesTo...>...</wsp:AppliesTo>
        <trust:RequestedProofToken>
            <trust:ComputedKey>.../CK/PSHA1</trust:ComputedKey>
        </trust:RequestedProofToken>
        <trust:Entropy>
          <trust:BinarySecret Type=".../Nonce">...</trust:BinarySecret>
        </trust:Entropy>
        <trust:Lifetime>
          <wsu:Created...>...</wsu:Created>
          <wsu:Expires...>...</wsu:Expires>
        </trust:Lifetime>
        <trust:KeySize>256</trust:KeySize>
      </trust:RequestSecurityTokenResponse>
    </trust:RequestSecurityTokenResponseCollection>

    The requested security token that is returned above is reproduced here. Note that the SubjectConfirmation Method is "holder-of-key", meaning that the client must illustrate proof of possession of the key contained in the EncryptedKey element of the Assertion. The EncryptedKey element is encrypted using the service provider's public key.

    <saml2:Assertion ID="..." IssueInstant="..." Version="2.0">
      <saml2:Issuer>DoubleItSTSIssuer</saml2:Issuer>
      <ds:Signature>...</ds:Signature>
      <saml2:Subject>
        <saml2:NameID NameQualifier="...">...</saml2:NameID>
        <saml2:SubjectConfirmation Method="...:cm:holder-of-key">
          <saml2:SubjectConfirmationData>
          ...
          <xenc:EncryptedKey
          ...
          </xenc:EncryptedKey>
          ...
          </saml2:SubjectConfirmationData>
       </saml2:SubjectConfirmation>
     </saml2:Subject>
     <saml2:Conditions NotBefore="..." NotOnOrAfter="..."></saml2:Conditions>
     <saml2:AttributeStatement>
       <saml2:Attribute...>
         <saml2:AttributeValue>authenticated</saml2:AttributeValue>
       </saml2:Attribute>
     </saml2:AttributeStatement>
    </saml2:Assertion>

    3.5) The Service Provider request

    Once the client receives the Issued Token from the STS, it recreates the symmetric key needed to communicate with the service provider, by combining the entropy received from the STS with its own entropy to form the session key. The (decrypted) SAML2 Assertion is inserted into the security header "as is". The symmetric key is referenced in the request via the following structure:

    <ds:KeyInfo Id="...">
      <wsse:SecurityTokenReference  wsse11:TokenType="...#SAMLV2.0" >
        <wsse:KeyIdentifier ValueType="...#SAMLID">...</wsse:KeyIdentifier>
      </wsse:SecurityTokenReference>
    </ds:KeyInfo>


    The Service Provider verifies the signature of the STS on the SAML Assertion, and then decrypts the EncryptedKey fragment using its private key, to obtain the symmetric key used to decrypt/verify the client request. As the confirmation method is "holder-of-key", the Service Provider ensures that the same key was used to sign some portion of the request, thus proving that the client is in possession of the key.
    Categories: Colm O hEigeartaigh

    Talend Service Factory 2.4.0 released

    Fri, 04/29/2011 - 16:36
    Talend Service Factory 2.4.0 has been released. It's based on Apache CXF 2.4.0, and so contains all of the security features in WSS4J 1.6.0, as well as the extensive support for SAML Assertions in CXF 2.4.0, that I have been blogging about for the last while.

    In addition to this, some examples are available for download, which illustrate how to get these (security) features working in an OSGi container. A lot of work has gone into making sure that security libraries such as Apache Santuario, Apache WSS4J and Opensaml can be used in an OSGi environment, so I recommend checking the examples out to see how it can be done.

    See Glen's blog for more information on the security examples. Also, see Sergey's blog for a discussion on some other examples based around transforming XML.
    Categories: Colm O hEigeartaigh

    SAML support in CXF 2.4.0

    Thu, 04/21/2011 - 13:28
    The recent Apache CXF 2.4.0 release contains support for creating, securing, processing and validating SAML Assertions according to the WS-Security 1.1 SAML Token Profile. As there is no documentation available as yet on this new feature, in this blog post I will go through a SAML system test in CXF 2.4.0 in detail.

    1) Running the Test

    To run the SAML system test you can do the following:

    svn co https://svn.apache.org/repos/asf/cxf/tags/cxf-2.4.0/systests/ws-securitycd ws-security
    mvn compile mvn test -Dtest=SamlTokenTest
    2) The Client

    2.1) The Client code

    You can view the source of the tests here. There are a number of tests involving creating SAML 1.1 and 2.0 assertions, and sending them to a service provider over various security bindings (Transport/Symmetric/Asymmetric). To simplify things, we will focus on the fourth test named "testSaml2OverAsymmetric". Minus some negative tests, the basic test client invocation code is as simple as:

    SpringBusFactory bf = new SpringBusFactory();URL busFile = SamlTokenTest.class.getResource("client/client.xml");Bus bus = bf.createBus(busFile.toString());SpringBusFactory.setDefaultBus(bus);SpringBusFactory.setThreadDefaultBus(bus);
    DoubleItService service = new DoubleItService();DoubleItPortType saml2Port = service.getDoubleItSaml2AsymmetricPort();((BindingProvider)saml2Port).getRequestContext().put("ws-security.saml-callback-handler", new SamlCallbackHandler());BigInteger result = saml2Port.doubleIt(BigInteger.valueOf(25));assert result.equals(BigInteger.valueOf(50));
    2.2) The WSDL

    The service is described in the WSDL here. Take a look at the WS-SecurityPolicy called "DoubleItSaml2AsymmetricPolicy", which defines the security requirements for the "DoubleItSaml2AsymmetricPort". It defines an Asymmetric Binding, where the InitiatorToken (which defines the credential used to sign the request) is always sent to the recipient, and the RecipientToken (which defines the credential used to encrypt the request) is never sent to the recipient. Both Initiator and Recipient tokens are defined as X509 tokens. The input and output policies in the WSDL enforce that the SOAP Body must be signed using the Initiator credential, and encrypted using the Recipient credential.

    In addition to specifying an asymmetric binding, the policy also defines a SignedSupportingToken, which contains a SAML (2.0) Token which is always sent to the recipient. In order to successfully invoke on the service, the client must include a SAML 2.0 token in the security header of the request. This policy looks like:

    <sp:SignedSupportingTokens>
        <wsp:Policy>
            <sp:SamlToken sp:IncludeToken="...AlwaysToRecipient">
                <wsp:Policy>
                    <sp:WssSamlV20Token11/>
                </wsp:Policy>
            </sp:SamlToken>
        </wsp:Policy></sp:SignedSupportingTokens>
    2.3) The Client configuration

    The client.xml referenced in the code block above contains a jaxws:client configuration for the DoubleItSaml2AsymmetricPort. It sets the following relevant jaxws:properties:
    1. ws-security.encryption.properties - The Crypto properties file which describes where to find the service provider's public key.
    2. ws-security.encryption.username -  The alias to use to obtain the service provider's public key from the keystore reference in the Crypto properties file above.
    3. ws-security.callback-handler - A CallbackHandler object which is expected to supply the password used to access the private key for signature creation, or decryption.
    4. ws-security.signature.properties - The Crypto properties file which describes where to find the client's public/private key.
    5. ws-security.signature.username - The alias to use to obtain the client's private key from the keystore reference in the Crypto properties file above.
    2.3) Creating a SAML token

    CXF 2.4.0 defines a new jaxws:property ("ws-security-saml-callback-handler") which specifies a CallbackHandler instance used to create SAML Assertions. This object is added to the outbound request context above dynamically, however it could also have been configured in the spring bean along with the other ws-security parameters. The CallbackHandler object used in this test can be seen here. The CallbackHandler implementation is expected to obtain a SAMLCallback object, and to set the appropriate values on this object, e.g. SAML version, Subject, issuer, Authentication/Authorization/Attribute Statements, etc. In the example provided in this test, it creates a SAML 2.0 assertion (by default), sets a mock issuer, subject and attribute statement, and sets a subject confirmation method of sender-vouches. Some code in WSS4J then constructs a SAML Assertion by processing this SAMLCallback object. It's easy to construct a SAML Assertion in this way, as the following (edited) code shows:

    SAMLCallback callback = (SAMLCallback) callbacks[i];callback.setSamlVersion(SAMLVersion.VERSION_20);callback.setIssuer("sts");String subjectName = "uid=sts-client,o=mock-sts.com";String subjectQualifier = "www.mock-sts.com";
    SubjectBean subjectBean = new SubjectBean(subjectName, subjectQualifier, SAML2Constants.CONF_SENDER_VOUCHES);callback.setSubject(subjectBean);
    AttributeStatementBean attrBean = new AttributeStatementBean();attrBean.setSubject(subjectBean);AttributeBean attributeBean = new AttributeBean();attributeBean.setSimpleName("subject-role");attributeBean.setAttributeValues(Collections.singletonList("system-user"));attrBean.setSamlAttributes(Collections.singletonList(attributeBean));callback.setAttributeStatementData(Collections.singletonList(attrBean));
    2.4) The service request

    The service request has a security header that contains the following elements:
    1. A BinarySecurityToken which consists of the X509Certificate of the client.
    2. A Timestamp.
    3. An EncryptedKey which consists of a symmetric key encrypted with the public key of the service provider, which is used to encrypt the SOAP Body.
    4. A SAML2 Assertion.
    5. A SecurityTokenReference to the SAML Assertion.
    6. A signature which signs the Timestamp, the SAML Assertion (via the SecurityTokenReference) and the (decrypted) SOAP body. The signing credential is the BinarySecurityToken element described above.
    The SAML 2.0 assertion looks like (edited):

    <saml2:Assertion ... Version="2.0">    <saml2:Issuer>sts</saml2:Issuer>    <saml2:Subject>      <saml2:NameID ...>uid=sts-client,o=mocksts.com</saml2:NameID>     <saml2:SubjectConfirmation Method="...:sender-vouches">     </saml2:SubjectConfirmation>   </saml2:Subject>   <saml2:Conditions NotBefore="..." NotOnOrAfter="..."/>    <saml2:AttributeStatement>     <saml2:Attribute FriendlyName="subject-role" ...>        <saml2:AttributeValue...>system-user</saml2:AttributeValue>     </saml2:Attribute>   </saml2:AttributeStatement></saml2:Assertion>
    One thing to note is that as the SAML Assertion has a subject confirmation method of "sender-vouches", the client will automatically add the quality-of-service requirement that the signature which covers the SOAP Body will also cover the SAML Assertion.

    3) The Server

    3.1) The Server code

    The SEI implementation is here, and the Server code itself is here.  The configuration is entirely driven through the WSDL and spring configuration, and so the code is as trivial as (edited):

    URL busFile = Server.class.getResource("server.xml");
    Bus busLocal = new SpringBusFactory().createBus(busFile);
    BusFactory.setDefaultBus(busLocal);
    setBus(busLocal);
    new Server();

    3.2) The Server configuration

    The server.xml configuration file referenced above can be seen here. The jaxws:Endpoint configuration for this port should be self-explanatory (edited):

    <jaxws:endpoint
           id="Saml2TokenOverAsymmetric"
           address="http://localhost:9001/DoubleItSaml2Asymmetric"
           serviceName="s:DoubleItService"
           endpointName="s:DoubleItSaml2AsymmetricPort"
           xmlns:s="http://WSSec/saml"
           implementor="org.apache.cxf.systest.ws.saml.server.DoubleItImpl"
           wsdlLocation="wsdl_systest_wssec/saml/DoubleItSaml.wsdl">
            
           <jaxws:properties>
               <entry key="ws-security.username" value="bob"/>
               <entry key="ws-security.callback-handler"
                      value="....KeystorePasswordCallback"/>
               <entry key="ws-security.signature.properties"
                      value="...bob.properties"/>
               <entry key="ws-security.encryption.properties"
                      value="...alice.properties"/>
               <entry key="ws-security.encryption.username" value="alice"/>
           </jaxws:properties>
     </jaxws:endpoint>

    The server will process the request as per the security policy in the WSDL, checking that there is a signature in the security header, that covers the SOAP Body and SAML Assertion, that the SOAP Body is Encrypted, that a Timestamp is present and valid, and that the SAML Assertion is present, and is the correct version, etc. Authentication is done on the basis of trust verification of the client's X509Certificate, which was used to verify the signature element.

    The SAML Assertion is ignored beyond this point for this system test. It is saved in the security processing results, so that a custom interceptor can do some additional validation or processing on it. In a future blog post, I will describe how to validate the Assertion that has been received in some custom manner.
    Categories: Colm O hEigeartaigh

    CXF 2.4.0 released

    Wed, 04/20/2011 - 16:27
    Apache CXF 2.4.0 has been released. CXF 2.4.0 contains a number of new and improved features in the security space. From the release statement:
    WS-Security improvements including support for SAML2 tokens, improved
    validation of security tokens, better performance, increased WS-I Basic
    Security Profile compliance, and much more.If those new features seem familiar, it's because most of the new functionality is driven by WSS4J 1.6.0, which I've blogged extensively about over the last few months. Probably the most significant new security functionality in CXF 2.4.0 is greatly enhanced support for SAML Assertions. CXF 2.4.0 supports the ability to create, secure, process and validate SAML Assertions in accordance with the WS-Security 1.1 SAML Token Profile. I intend to blog in more detail how to use these new features in CXF 2.4.0 over the next while.

    See Dan Kulp's blog for more in-depth thoughts on the new release.
    Categories: Colm O hEigeartaigh

    WSS4J 1.6.0 released

    Fri, 04/15/2011 - 13:28
    WSS4J 1.6.0 has been released:
    The Apache Web Services team is pleased to announce the release of WSS4J 1.6.0. WSS4J 1.6.0 features support for SAML2 assertions, JSR-105 support, better spec compliance, performance work, support for trust-stores and a lot more besides. It is not API-compatible with the 1.5.x series of releases. For more information on the new features and changes in WSS4J 1.6.0 go to: http://ws.apache.org/wss4j/wss4j16.html To download WSS4J 1.6.0 go to: http://ws.apache.org/wss4j/download.html-- The Apache Web Services Team
    Categories: Colm O hEigeartaigh

    [WSS4J 1.6] Introducing Validators

    Tue, 04/05/2011 - 14:18
    WSS4J 1.6 introduces the concept of a Validator, for validating credentials that have been processed by a Processor instance. This task was covered by the JIRA WSS-266.

    An inbound security header is processed by WSS4J by iterating through each child element of the header, and by calling the appropriate Processor implementation to deal with each element. In WSS4J 1.5.x, some processors perform validation on the received token (e.g. UsernameTokens), whereas others store the processing results for later verification by third-party WS-Handler implementations (e.g. Timestamp verification, Certificate trust verification). There are some problems with this approach:
    • It is not consistent, some processors perform validation, others do not.
    • There is a potential security hole, in that it is assumed third-party code will know to validate the credentials that the WSS4J processors do not validate.
    • WSS4J will continue to process the rest of the security header even if the Timestamp is invalid, or the certificate non-trusted, which could lead to denial-of-service attacks.
    • There is no separation of concerns between processing the token and validating the token. If you want to change how the token is validated, you must replace the processor instance.
    WSS4J 1.6 has moved Timestamp verification and certificate trust validation back into the processing of the security header, thus solving the first three points above. The fourth point is met by the new concept of Validators, as well as some changes to the way Processors and CallbackHandler implementations are used in WSS4J 1.6.

    In WSS4J 1.5.x, CallbackHandler implementations are used in different ways by different processors, sometimes they are expected to verify a password (as for processing UsernameTokens), and other times they are expected to supply a password (as for decryption). In WSS4J 1.6, CallbackHandler implementations are only expected to supply a password (if it exists) to the processors. The Processor implementations do not perform any validation of the security token, instead they package up the processed token, along with any (password) information extracted from the CallbackHandler, and hand it off to a Validator implementation for Validation.

    The Processor implementations get the specific Validator implementation to use via the RequestData parameter, which in turn asks a WSSConfig object for the Validator implementation. If the Validator is null, then no Validation is performed on the received token. The Processor then stores the received token as normal. WSS4J 1.6 comes with several default Validators, which are:
    • NoOpValidator: Does no processing of the credential
    • TimestampValidator: Validates a Timestamp
    • UsernameTokenValidator: Validates a UsernameToken
    • SignatureTrustValidator: Verifies trust in a signature
    • SamlAssertionValidator: Checks some HOK requirements on a SAML Assertion, and verifies trust on the (enveloped) signature.
    There are some additional WSSecurityEngineResult constants that pertain to the Validator implementations:
    • TAG_VALIDATED_TOKEN: Indicates that the token corresponding to this result has been validated by a Validator implementation. Some of the processors do not have a default Validator implementation.
    • TAG_TRANSFORMED_TOKEN: A Validator implementation may transform a credential (into a SAML Assertion) as a result of Validation. This tag holds a reference to an AssertionWrapper instance, that represents a transformed version of the validated credential.
    To validate an inbound UsernameToken in some custom way, simply associate the NoOpValidator with the UsernameToken QName in the WSSConfig of the RequestData object used to supply context information to the processors. After WSS4J has finished processing the security header, then extract the WSSecurityEngineResult instance corresponding to the WSConstants.UT action, and perform some custom validation on the token.

    An example of how to add a custom Validator implementation is the STSTokenValidator in CXF 2.4.0. The STSTokenValidator tries to validate a received SAML Assertion locally, and if that fails, it dispatches it to a Security Token Service (STS) via the WS-Trust interface for validation. It also supports validating a UsernameToken and BinarySecurityToken in the same manner. The SecurityConstants class defines some configuration tags for specifying a custom validator for inbound SAML1, SAML2, UsernameToken, BinarySecurityToken, Signature and Timestamps. The STSTokenValidator can be configured by associating it with the appropriate configuration tag.
    Categories: Colm O hEigeartaigh

    [WSS4J 1.6] SAML property changes

    Sun, 03/13/2011 - 16:02
    A previous blog entry described how WSS4J 1.6 will have support for creating, parsing, signing, verifying, etc. SAML 2 assertions. WSS4J 1.5.x had limited support for creating and signing SAML 1.1 assertions via the default SAMLIssuer implementation, combined with a properties file. These configuration values consisted of:
    • org.apache.ws.security.saml.issuerClass - The SAML Issuer implementation (defaults to "org.apache.ws.security.saml.SAMLIssuerImpl").
    • org.apache.ws.security.saml.issuer.cryptoProp.file - The crypto properties file corresponding to the issuer crypto instance, if the assertion is to be signed.
    • org.apache.ws.security.saml.issuer.key.name - The KeyStore alias for the issuer key.
    • org.apache.ws.security.saml.issuer.key.password - The KeyStore password for the issuer key.
    • org.apache.ws.security.saml.issuer - The issuer name
    • org.apache.ws.security.saml.issuer.sendKeyValue - Whether to send the key value or the X509Certificate. Defaults to: "false".
    • org.apache.ws.security.saml.subjectNameId.name - The Subject DN.
    • org.apache.ws.security.saml.subjectNameId.qualifier - The Subject qualifier.
    • org.apache.ws.security.saml.authenticationMethod - The authentication method (e.g. "password").
    • org.apache.ws.security.saml.confirmationMethod - The confirmation method, either "senderVouches" or "keyHolder".
    The configuration tags for WSS4J 1.5.x completely controlled the creation and signing of a SAML 1.1 Assertion, and hence produced only a very limited set of possible assertions.  WSS4J 1.6 takes a different approach, where the configuration tags correspond to the configuration of the issuer, i.e. whether to sign the assertion or not, the issuer name, crypto instance, etc. All instructions about how to create the SAML Assertion itself, are left to a CallbackHandler implementation.

    The following configuration tags in WSS4J 1.6 are exactly the same as in WSS4J 1.5.x:
    • org.apache.ws.security.saml.issuerClass - The SAML Issuer implementation (defaults to "org.apache.ws.security.saml.SAMLIssuerImpl").
    • org.apache.ws.security.saml.issuer.cryptoProp.file - The crypto properties file corresponding to the issuer crypto instance, if the assertion is to be signed.
    • org.apache.ws.security.saml.issuer.key.name - The KeyStore alias for the issuer key.
    • org.apache.ws.security.saml.issuer.key.password - The KeyStore password for the issuer key.
    • org.apache.ws.security.saml.issuer - The issuer name
    • org.apache.ws.security.saml.issuer.sendKeyValue - Whether to send the key value or the X509Certificate. Defaults to: "false".
    The following configuration tags are new to WSS4J 1.6:
    • org.apache.ws.security.saml.issuer.signAssertion - Whether the SAMLIssuer implementation will sign the assertion or not. Defaults to: "false".
    • org.apache.ws.security.saml.callback - The name of the SAML CallbackHandler implementation used to populate the SAML Assertion.

    [WSS4J 1.6] Basic Security Profile 1.1 compliance

    Tue, 03/08/2011 - 14:44
    The Basic Security Profile (BSP) 1.1 specification provides an industry-standard way of making sure that different WS-Security stacks can communicate with each other, by clarifying and narrowing the scope of the various WS-Security standards. WSS4J 1.5.x does not implement the BSP in any meaningful way. The WSSConfig class supports a "isWsiBSPCompliant" method (default is false), which will enable the generation of an InclusivePrefix list for signature generation, something that is mandated by the BSP spec.

    WSS4J 1.6 provides support for the BSP 1.1 specification, in so far as it pertains to the core WS-Security specifications that WSS4J supports. The enforcing of BSP compliance for inbound messages is controlled by the WSSConfig class, as per WSS4J 1.5.x. An important change is that BSP compliance is now turned on by default. In addition, a new WSHandlerConstants configuration parameter has been added so that BSP compliance can be controlled via a WSHandler implementation.

    Pages