Colm O hEigeartaigh

Subscribe to Colm O hEigeartaigh feed
Colm O hEigeartaighhttp://www.blogger.com/profile/10711987281965801793noreply@blogger.comBlogger241125
Updated: 4 hours 37 min ago

Apache CXF Fediz 1.2.0 tutorial - part III

Wed, 07/15/2015 - 17:22
This is the third in a series of blog posts on the new features and changes in Apache CXF Fediz 1.2.0. The previous blog entry described how different client authentication mechanisms are supported in the IdP, and how to configure client authentication via an X.509 certificate, a new feature in Fediz 1.2.0. Another new authentication mechanism in Fediz 1.2.0 is the ability to authenticate to the IdP using Kerberos, which we will cover in this article.

1) Kerberos client authentication in the IdP

Recall that the Apache Fediz IdP in 1.2.0 supports different client authentication methods by default using different URL paths. In particular for Kerberos, the URL path is:
  • /federation/krb -> authentication using Kerberos
The default value for the "wauth" parameter added by the service provider to the request to activate this URL path is:
  • http://docs.oasis-open.org/wsfed/authorization/200706/authntypes/SslAndKey
When the IdP receives a request at the URL path configured for Kerberos, it sends back a request for a Negotiate Authorization header if none is present. Otherwise it parses the header and BASE-64 decodes the Kerberos token and dispatches it to the configured authentication provider. Kerberos tokens are authenticated in the IdP via the STSKrbAuthenticationProvider, which is configured in the Spring security-config.xml

2) Authenticating Kerberos tokens in the IdP

The IdP supports two different ways of validating Kerberos tokens:
  • Passthrough Authentication. Here we do not authenticate the Kerberos token at all in the IdP, but pass it through to the STS for authentication. This is similar to what is done for the Username/Password authentication case. The default security binding of the STS for this scenario requires a KerberosToken Supporting Token. This is the default way of authenticating Kerberos tokens in the IdP.
  • Delegation. If delegation is enabled in the IdP, then the received token is validated locally in the IdP. The delegated credential is then used to get a new Kerberos Token to authenticate the STS call "on behalf of" the original user. 
To enable the delegation scenario, simply update the STSKrbAuthenticationProvider bean in the security-config.xml,
set the "requireDelegation" property to "true", and configure the kerberosTokenValidator property to validate the received Kerberos token:

Categories: Colm O hEigeartaigh

Securing Apache CXF with Apache Camel

Fri, 07/10/2015 - 18:45
The previous post I wrote about how to integrate Apache CXF with Apache Camel. The basic test scenario involved using an Apache CXF proxy service to authenticate clients, and Apache Camel to route the authenticated requests to a backend service, which had different security requirements to the proxy. In this post, we will look at a slightly different scenario, where the duty of authenticating the clients shifts from the proxy service to Apache Camel itself. In addition, we will look at how to authorize the clients via different Apache Camel components.

For a full description of the test scenario see the previous post. The Apache CXF based proxy service receives a WS-Security UsernameToken, which is used to authenticate the client. In the previous scenario, this was done at the proxy by supplying a CallbackHandler instance to verify the given username and password. However, this time we will just configure the proxy to pass the received credentials through to the route instead of authenticating them. This can be done by setting the JAX-WS property "ws-security.validate.token" to "false":

So now it is up to the Camel route to authenticate and authorize the user credentials. Here are two possibilities using Apache Shiro and Spring Security.

1) Apache Shiro

I've covered previously how to use Apache Shiro to authenticate and authorize web service invocations using Apache CXF. Apache Camel ships with a camel-shiro component which allows you to authenticate and authorize Camel routes. The test-case can be downloaded and run here:
  • camel-cxf-proxy-shiro-demo: Some authentication and authorization tests for an Apache CXF proxy service using the Apache Camel Shiro component.
Username, passwords and roles are stored in a file and parsed in a ShiroSecurityPolicy object:

The Camel route is as follows:


Note that the shiroHeaderProcessor bean processes the result from the proxy before applying the Shiro policy. This processor retrieves the client credentials (which are stored as a JAAS Subject in a header on the exchange) and extracts the username and password, storing them in special headers that are used by the Shiro component in Camel to get the username and password for authentication. 

The authorization use-case uses the same route, however the ShiroSecurityPolicy bean enforces that the user must have a role of "boss" to invoke on the backend service:


2) Spring Security 

I've also covered previously how to use Spring Security to authenticate and authorize web service invocations using Apache CXF. Apache Camel ships with a camel-spring-security component which allows you to authenticate and authorize Camel routes. The test-case can be downloaded and run here:
Like the Shiro test-case, username, passwords and roles are stored in a file, which is used to create an authorizationPolicy bean:
The Camel route is exactly the same as in the Shiro example above, except that a different processor implementation is used. The SpringSecurityHeaderProcessor bean used in the tests translates the user credentials into a Spring Security UsernamePasswordAuthenticationToken principal, which is added to the JAAS Subject stored under the Exchange.AUTHENTICATION header. This principal is then used by the Spring Security component to authenticate the request.

To authorize the request, a different authorizationPolicy configuration is required:


Categories: Colm O hEigeartaigh

Integrating Apache CXF with Apache Camel

Mon, 07/06/2015 - 12:51
Apache Camel provides support for integrating Apache CXF endpoints via the camel-cxf component. A common example of the benefits of using Apache Camel with webservices is when a proxy service is required to translate some client request into a format that is capable of being processed by some backend service. Apache Camel ships with an example where a backend service consumes SOAP over JMS, and a proxy service translates a SOAP over HTTP client request into SOAP over JMS. In this post, we will show an example of how to use this proxy pattern to secure a client invocation to a backend service via a proxy, when the backend service and proxy have different security requirements.

The test scenario is as follows. The backend service is an Apache CXF-based JAX-WS "double-it" service that can only be called by trusted clients. However, we don't want to give the backend service the responsibility to authenticate clients. A CXF-based proxy service will be responsible for authenticating clients, and then routing the authenticated requests to the backend service via Apache Camel. The backend service is secured via TLS with client authentication, meaning that we have direct trust between the proxy service and the backend service. Clients must authenticate to the proxy service via a WS-Security UsernameToken over TLS.

The test-case can be downloaded and run here:
 The CXF proxy is configured as follows:

The CallbackHandler supplies the password to authenticate client passwords. The Camel route is defined as:

The headerFilterStrategy reference is to a CxfHeaderFilterStrategy bean which instructs Camel to drop the message headers (we don't need the security header beyond the proxy, as the proxy is responsible for authenticating the client). Messages are routed to the "doubleItService", which is defined as follows:


Categories: Colm O hEigeartaigh

Using SSH/SCP/SFTP with Apache Camel

Thu, 07/02/2015 - 15:46
Apache Camel contains a number of components to make it easy to work with SSH/SCP/SFTP. I've created a new camel-ssh testcase in github to illustrate how to use these various components, continuing on from previous posts describing the security capabilities of Apache Camel:
  • SSHTest: This test-case shows how to use the Apache Camel SSH component. The test fires up an Apache MINA SSHD server, which has been configured to allow authenticated users to execute arbitrary commands (ok not very safe...). Some files that contain unix commands are read in via a Camel route, executed using the SSH component, and the results are stored in target/ssh_results.
  • SCPTest: This test-case shows how to use the Apache Camel JSCH component (which supports SCP using JSCH). An Apache MINA SSHD server is configured that allows SCP. Some XML files are read in via a Camel route, and copied using SCP to a target directory on the server (which maps to target/storage for the purposes of this test).
  • SFTPTest: This test-case shows how to use the Apache Camel FTP component. An Apache MINA SSHD server is configured that allows SFTP. Some XML files are read in via a Camel route, and copied using SFTP to a target directory on the server (target/storage_sftp).
Categories: Colm O hEigeartaigh

An STS JAAS LoginModule for Apache CXF

Tue, 06/30/2015 - 13:27
Last year I blogged about how to use JAAS with Apache CXF, and the different LoginModules that were available. Recently, I wrote another article about using a JDBC LoginModule with CXF. This article will cover a relatively new JAAS LoginModule  added to CXF for the 3.0.3 release. It allows a service to dispatch a Username and Password to a STS (Security Token Service) instance for authentication via the WS-Trust protocol, and also to retrieve the user's roles by extracting them from a SAML token returned by the STS.

1) The STS JAAS LoginModule

The new STS JAAS LoginModule is available in the CXF WS-Security runtime module. It takes a Username and Password from the Callbackhandler passed to the LoginModule, and uses them to create a WS-Security UsernameToken structure. What happens then depends on a configuration setting in the LoginModule.

If the "require.roles" property is set, then the UsernameToken is added to a WS-Trust "Issue" request to the STS, and a "TokenType" attribute is sent in the request (defaults to the standard "SAML2" URI, but can be configured). The client also adds a WS-Trust "Claim" to the request that tells the STS to add the role of the authenticated end user to the request. How the token is added to the WS-Trust request depends on whether the "disable.on.behalf.of" property is set or not. By default, the token is added as an "OnBehalfOf" token in the WS-Trust request. However, if "disable.on.behalf.of" is set to "true", then the credentials are used according to the WS-SecurityPolicy of the STS endpoint. For example, if the policy requires a UsernameToken, then the credentials are added to the security header of the WS-Trust request. If the "require.roles" property is not set, the the UsernameToken is added to a WS-Trust "Validate" request.

The STS validates the received UsernameToken credentials supplied by the end user, and then either creates a token (if the Issue binding was used), or just returns a simple response telling the client whether the validation was successful or not. In the former use-case, the token that is returned is cached meaning that the end user does not have to re-authenticate until the token expires from the cache.

The LoginModule has the following configuration properties:
  • require.roles - If this is defined, then the WS-Trust Issue binding is used, passing the value specified for the "token.type" property as the TokenType, and the "key.type" property for the KeyType. It also adds a Claim to the request for the default "role" URI.
  • disable.on.behalf.of - Whether to disable passing Username + Password credentials via "OnBehalfOf".
  • disable.caching - Whether to disable caching of validated credentials. Default is "false". Only applies when "require.roles" is defined.
  • wsdl.location - The location of the WSDL of the STS
  • service.name - The service QName of the STS
  • endpoint.name - The endpoint QName of the STS
  • key.size - The key size to use (if requesting a SymmetricKey KeyType). Defaults to 256.
  • key.type - The KeyType to use. Defaults to the standard "Bearer" URI.
  • token.type - The TokenType to use. Defaults to the standard "SAML2" URI.
  • ws.trust.namespace - The WS-Trust namespace to use. Defaults to the standard WS-Trust 1.3 namespace.
In addition, any of the standard CXF security configuration tags that start with "ws-security." can be used as documented here. Sometimes it is necessary to set some security configuration depending on the security policy of the WSDL.

Here is an example of the new JAAS LoginModule configuration:



2) A testcase for the new LoginModule

Using an STS via WS-Trust for authentication and authorization can be quite difficult to set up and understand, but the new LoginModule makes it easy. I created a testcase + uploaded it to github:
  • cxf-jaxrs-jaas-sts: This project demonstrates how to use the new STS JAAS LoginModule in CXF to authenticate and authorize a user. It contains a "double-it" module which contains a "double-it" JAX-RS service. It is secured with JAAS at the container level, and requires a role of "boss" to access the service. The "sts" module contains a Apache CXF STS web application which can authenticate users and issue SAML tokens with embedded roles.
To run the test, download Apache Tomcat and do "mvn clean install" in the testcase above. Then copy both wars and the jaas configuration file to the Apache Tomcat install (${catalina.home}):
  • cp double-it/target/cxf-double-it.war ${catalina.home}/webapps
  • cp sts/target/cxf-sts.war ${catalina.home}/webapps
  • cp double-it/src/main/resources/jaas.conf ${catalina.home}/conf
Next set the following system property:
  • export JAVA_OPTS=-Djava.security.auth.login.config=${catalina.home}/conf/jaas.conf
Finally, start Tomcat, open a web browser and navigate to:

http://localhost:8080/cxf-double-it/doubleit/services/100

Use credentials "alice/security" when prompted. The STS JAAS LoginModule takes the username and password, and dispatches them to the STS for validation.

    Categories: Colm O hEigeartaigh

    A new Crypto implementation in Apache WSS4J

    Mon, 06/29/2015 - 16:51
    Apache WSS4J uses the Crypto interface to get keys and certificates for asymmetric encryption/decryption and signature creation/verification. In addition, it also takes care of verifying trust in an X.509 certificate used to sign some portion of the message. WSS4J currently ships with three Crypto implementations:
    • Merlin: The standard implementation, based around two JDK keystores for key/cert retrieval, and trust verification.
    • CertificateStore: Holds an array of X509 Certificates. Can only be used for encryption and signature verification.
    • MerlinDevice: Based on Merlin, allows loading of keystores using a null InputStream - for example on a smart-card device.
    The next release(s) of WSS4J, 2.0.5 and 2.1.2, will contain a fourth implementation:
    • MerlinAKI: A new Merlin-based Crypto implementation that searches the truststore for the issuing certificate using the AuthorityKeyIdentifier extension bytes of the signing certificate, as opposed to the issuer DN.
    Trust verification for the standard/default Merlin implementation works as follows:
    1. Is the signing cert contained in the keystore/truststore? If yes, then trust verification succeeds. This can be combined with using regular expressions on the Subject DN as well.
    2. If not, then get the issuing cert by reading the Issuer DN from the signing cert. Then search for this cert in the keystore/truststore. 
    3. If the issuer cert is found, then form a cert path containing the signing cert, the issuing cert and any subsequent issuing cert of that cert. Then validate the cert path.
    However, the retrieval of the issuing cert in step 2 above falls down under certain rare scenarios, where there may not be a 1-to-1 link between the Subject DN of a certificate and a public key. This is where the new MerlinAKI implementation comes in. Instead of searching for the issuing cert using the issuer DN of the signing cert, it instead uses BouncyCastle to retrieve the AuthorityKeyIdentifier extension bytes (if present) from the cert. It then searches for the issuing cert by seeing which of the certs in the truststore contain a SubjectKeyIdentifier extension with a matching identifier value. You can switch to use MerlinAKI simply by changing the name of the Crypto provider in the Crypto properties file:


    Categories: Colm O hEigeartaigh

    Using AWS KMS with Apache CXF to secure passwords

    Fri, 06/26/2015 - 13:16
    The previous tutorial showed how the AWS Key Management Service (KMS) can be used to generate symmetric encryption keys that can be used with WS-Security to encrypt and decrypt a service request using Apache CXF. It is also possible to use the KMS to secure keystore passwords for asymmetric encryption and signature, that are typically stored in properties files when using WS-Security with Apache CXF.

    1) Encrypting passwords in a Crypto properties file

    Apache CXF uses the WSS4J Crypto interface to get keys and certificates for asymmetric encryption/decryption and for signature creation/verification. Merlin is the standard implementation, based around two JDK keystores for key/cert retrieval, and trust verification. Typically, a Crypto implementation is loaded and configured via a Crypto properties file. For example:


    However one issue with this style of configuration is that the keystore password is stored in plaintext in the file. Apache WSS4J 2.0.0 introduced the ability to store encrypted passwords in the crypto properties file instead. A PasswordEncryptor interface was defined to allow for the encryption/decryption of passwords, and a default implementation based on Jasypt was made available in the release. In this case, the master password used to decrypt the encrypted keystore password was retrieved from a CallbackHandler implementation.

    2) Using KMS to encrypt keystore passwords

    Instead of using the Jasypt PasswordEncryptor implementation provided by default in Apache WSS4J, it is possible to use instead the AWS KMS to decrypt encrypted keystore passwords stored in crypto properties files. I've updated the test-case introduced in the previous tutorial with an asymmetric encryption test-case, where a SOAP service invocation is encrypted using a WS-SecurityPolicy AsymmetricBinding policy.

    The first step in running the test-case is to follow the previous tutorial in terms of registering for AWS, creating a user "alice" and a corresponding customer master key. One you have this, then run the "testEncryptedPasswords" test available here, which outputs the encrypted passwords for the client and service keystores ("cspass" and "sspass"). Copy the output + paste them into the clientEncKeystore.properties and serviceEncKeystore.properties in the "ENC()" tags. For example:


    The client and service configure a custom PasswordEncryptor implementation designed to decrypt the encrypted keystore password using KMS. The KMSPasswordEncryptor is spring-loaded in the client and service configuration, and must be updated with the access key id, secret key, master key id, etc. as defined earlier. Of course this means that the secret key is in plaintext in a spring configuration file in this example. However, it could be obtained via a system property or some other means, and is more secure than storing a plaintext keystore password in a properties file. Once the KMSPasswordEncryptor is properly configured, then the AsymmetricTest can be run, and you will see the secured service request and response in the console window.


    Categories: Colm O hEigeartaigh

    Integrating AWS Key Management Service with Apache CXF

    Thu, 06/25/2015 - 13:20
    Apache CXF supports a wide range of standards designed to help you secure a web service request, from WS-Security for SOAP requests, to XML Security and JWS/JWE for XML/JSON REST requests. All of these standards provide for using symmetric keys to encrypt requests, and then using a master key (typically a public key associated with an X.509 certificate) to encrypt the symmetric key, embedding this information somewhere in the request. The usual use-case is to generate random bytes for the symmetric key. But what if you wanted instead to manage the secret keys in some way? Or if your client did not have access to sufficient entropy to generate truly random bytes? In this article, we will look at how to use the AWS Key Management Service to perform this task for us, in the context of an encrypted SOAP request using WS-Security.

    1) AWS Key Management Service

    The AWS Key Management Service allows us to create master keys and data keys for users defined in the AWS Identity and Access Management service. Once we have created a user, and a corresponding master key for the user (which is only stored in AWS and cannot be exported), we can ask the Key Management Service to issue us a data key (using either AES 128 or 256), and an encrypted data key. The idea is that the data key is used to encrypt some data and is then disposed of. The encrypted data key is added to the request, where the recipient can ask the Key Management Service to decrypt the key, which can be then be used to decrypt the encrypted data in the request.

    The first step is to register for Amazon AWS here. Once we have registered, we need to create a user in the Identity and Access Management service. Create a new user "alice", and make a note of the access key and secret access key associated with "alice". Next we need to write some code to obtain keys for "alice" (documentation). First we must create a client:

    AWSCredentials creds = new BasicAWSCredentials(<access key id>, <secret key>);
    AWSKMSClient kms = new AWSKMSClient(creds);
    kms.setEndpoint("https://kms.eu-west-1.amazonaws.com");

    Next we must create a customer master key for "alice":

    String desc = "Secret encryption key";
    CreateKeyRequest req = new CreateKeyRequest().withDescription(desc);
    CreateKeyResult result = kms.createKey(req);

    The CreateKeyResult object returned as part of the key creation process will contain a key Id, which we will need later.

    2) Using AWS Key Management Service keys with WS-Security

    As mentioned above, the typical process for WS-Security when encrypting a request, is to generate some random bytes to use as the symmetric encryption key, and then use a key wrap algorithm with another key (typically a public key) to encrypt the symmetric key. Instead, we will use the AWS Key Management Service to retrieve the symmetric key to encrypt the request. We will store the encrypted form of the symmetric key in the WS-Security EncryptedKey structure, which will reference the Customer Master Key via a "KeyName" pointing to the Key Id.

    I have created a project that can be used to demonstrate this integration:
    • cxf-amazon-kms: This project contains a number of tests that show how to use the AWS Key Management Service with Apache CXF.
    The first task in running the test (assuming the steps followed in point 1 above were followed) is to edit the client configuration, entering the correct values in the CommonCallbackHandler for the access key id, secret key, endpoint, and master key id as gathered above, ditto for the service configuration. The CommonCallbackHandler uses the AWS Key Management Service API to create the symmetric key on the sending side, and to decrypt it on the receiving side. Then to run the test simply remove the "org.junit.Ignore" annotation, and the encrypted web service request can be seen in the console:


    Categories: Colm O hEigeartaigh

    Using a JDBC JAAS LoginModule with Apache CXF

    Tue, 06/23/2015 - 13:20
    Last year I wrote a blog entry giving an overview of the different ways that you can use JAAS with Apache CXF for authenticating and authorizing web service calls. I also covered some different login modules and linked to samples for authenticating a Username + Password to LDAP, as well as Kerberos Tokens to a KDC. This article covers how to use JAAS with Apache CXF to authenticate a Username + Password to a database via JDBC.

    The test-case is available here:
    • cxf-jdbc: This project contains a number of tests that show how an Apache CXF service endpoint can authenticate and authorize a client using JDBC.
    It contains two tests, one dealing with authentication (no roles required by the service) and the other with authorization (a specific role is required). Both tests involve a JAX-WS service invocation, where the service requires a WS-Security UsernameToken over TLS. In each case, the service configures Apache WSS4J's JAASUsernameTokenValidator using the context name "jetty". The JAAS configuration file contains an entry for the "jetty" context, which references the Jetty JDBCLoginModule:

    The configuration of the JDBCLoginModule is easy to follow. The "dbUrl" refers to the JDBC connection URL (in this case an in-memory Apache Derby instance). The table containing user data is "app.users", where the fields used for usernames and passwords are "name" and "password" respectively. Similarly, the table containing role data is "app.roles", where the fields used for usernames + roles are "name" and "role" respectively.

    The tests use Apache Derby as an in-memory database. It is created in code as follows:


    Then the following SQL file is read in, and each statement is executed using the statement Object above:


    Categories: Colm O hEigeartaigh

    Apache CXF Fediz 1.2.0 tutorial - part II

    Thu, 06/11/2015 - 14:47
    This is the second in a series of blog posts on the new features and changes in Apache CXF Fediz 1.2.0. The previous blog entry gave instructions about how to deploy the Fediz IdP and a sample service application in Apache Tomcat. This article describes how different client authentication methods are supported in the IdP, and how they can be selected by the service via the "wauth" parameter. Then we will extend the previous tutorial by showing how to authenticate to the IdP using a client certificate in the browser, as opposed to entering a username + password.

    1) Supporting different client authentication methods in the IdP

    The Apache Fediz IdP in 1.2.0 supports different client authentication methods by default using different URL paths, as follows:
    • /federation -> the main entry point
    • /federation/up -> authentication using HTTP B/A
    • /federation/krb -> authentication using Kerberos
    • /federation/clientcert -> authentication using a client cert
    The way it works is as follows. The service provider (SP) should use the URL for the main entry point (although the SP has the option of choosing one the more specific URLs as well). The IdP extracts the "wauth" parameter from the request ("default" is the default value), and looks for a matching key in the "authenticationURIs" section of the service configuration. For example:

    <property name="authenticationURIs">
        <util:map>
            <entry key="default" value="federation/up" />
            <entry key="http://docs.oasis-open.org/wsfed/authorization/200706/authntypes/SslAndKey" value="federation/krb" />
            <entry key="http://docs.oasis-open.org/wsfed/authorization/200706/authntypes/default" value="federation/up" />
            <entry key="http://docs.oasis-open.org/wsfed/authorization/200706/authntypes/Ssl" value="federation/clientcert" />
        </util:map>
    </property>

    If a matching key is found for the wauth value, then the browser gets redirected to the associated URL. Therefore, a service provider can specify a value for "wauth" in the plugin configuration, and select the client authentication mode as a result. The values defined for "wauth" above are taken from the specification, but can be changed if required. The service provider can specify the value for "wauth" by using the "authenticationType" configuration tag, as documented here.

    2) Client authentication using a certificate

    A new feature of Fediz 1.2.0 is the ability for a client to authenticate to the IdP using a certificate embedded in the browser. To see how this works in practice, please follow the steps given in the previous tutorial to set up the IdP and service web application in Apache Tomcat. To switch to use client certificate authentication, only one change is required in the service provider configuration:
    • Edit ${catalina.home}/conf/fediz_config.xml, and add the following under the "protocol" section: <authenticationType>http://docs.oasis-open.org/wsfed/authorization/200706/authntypes/Ssl</authenticationType>
    The next step is to add a client certificate to the browser that you are using. To avoid changing the IdP TLS configuration, we will just use the same certificate / private key that is used by the IdP on the client side for the purposes of this demo. First, we need to convert the IdP key from JKS to PKCS12. So take the idp-ssl-key.jks configured in the previous tutorial and run:
    • keytool -importkeystore -srckeystore idp-ssl-key.jks -destkeystore idp-ssl-key.p12 -srcstoretype JKS -deststoretype PKCS12 -srcstorepass tompass -deststorepass tompass -srcalias mytomidpkey -destalias mytomidpkey -srckeypass tompass -destkeypass tompass -noprompt
    I will use Chrome for the client browser. Under Settings, Advanced Settings, "HTTPS/SSL", click on the Manage Certificates button, and add the idp-ssl-key.p12 keystore above using the password "tompass":
    Next, we need to tell the STS to trust the key used by the client (you can skip these steps if using Fediz 1.2.1):
    • First, export the certificate as follows: keytool -keystore idp-ssl-key.jks -storepass tompass -export -alias mytomidpkey -file MyTCIDP.cer
    • Take the ststrust.jks + import the cert: keytool -import -trustcacerts -keystore ststrust.jks -storepass storepass -alias idpcert -file MyTCIDP.cer -noprompt
    • Finally, copy the modified ststrust.jks into the STS: ${catalina.home}/webapps/fediz-idp-sts/WEB-INF/classes
    The last configuration step is to tell the STS where to retrieve claims for the cert. We will just copy the claims for Alice:
    • Edit ${catalina.home}/webapps/fediz-idp-sts/WEB-INF/userClaims.xml
    • Add the following under "userClaimsREALMA": <entry key="CN=localhost" value-ref="REALMA_aliceClaims" />
    Now restart Tomcat and navigate to the service URL:
    • https://localhost:8443/fedizhelloworld/secure/fedservlet
    Select the certificate that we have uploaded, and you should be able to authenticate to the IdP and be redirected back to the service, without having to enter any username/password credentials!
    Categories: Colm O hEigeartaigh

    Apache CXF Fediz 1.2.0 tutorial - part I

    Wed, 06/10/2015 - 17:16
    The previous blog entry gave an overview of the new features in Apache CXF Fediz 1.2.0. This post first focuses on setting up and running the IdP (Identity Provider) and the sample simpleWebapp in Apache Tomcat.

    1) Deploying the 1.2.0 Fediz IdP in Apache Tomcat

    Download Fediz 1.2.0 and extract it to a new directory (${fediz.home}). We will use a Apache Tomcat 7 container to host the Idp. To deploy the IdP to Tomcat:
    • Create a new directory: ${catalina.home}/lib/fediz
    • Edit ${catalina.home}/conf/catalina.properties and append ',${catalina.home}/lib/fediz/*.jar' to the 'common.loader' property.
    • Copy ${fediz.home}/plugins/tomcat/lib/* to ${catalina.home}/lib/fediz
    • Copy ${fediz.home}/idp/war/* to ${catalina.home}/webapps
    • Download and copy the hsqldb jar (e.g. hsqldb-1.8.0.10.jar) to ${catalina.home}/lib
    Now we need to set up TLS:
    • The keys that ship with Fediz 1.2.0 are 1024 bit DSA keys, which will not work with most modern browsers (this will be fixed for 1.2.1). 
    • So we need to generate a new key: keytool -genkeypair -validity 730 -alias mytomidpkey -keystore idp-ssl-key.jks -dname "cn=localhost" -keypass tompass -storepass tompass -keysize 2048 -keyalg RSA
    • Export the cert: keytool -keystore idp-ssl-key.jks -storepass tompass -export -alias mytomidpkey -file MyTCIDP.cer
    • Create a new truststore with the cert: keytool -import -trustcacerts -keystore idp-ssl-trust.jks -storepass ispass -alias mytomidpkey -file MyTCIDP.cer -noprompt
    • Copy idp-ssl-key.jks and idp-ssl-trust.jks to ${catalina.home}.
    • Copy both jks files as well to ${catalina.home}/webapps/fediz-idp/WEB-INF/classes/ (after Tomcat is started)
    • Edit the TLS Connector in ${catalina.home}/conf/server.xml', e.g.: <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true" clientAuth="want" sslProtocol="TLS" keystoreFile="idp-ssl-key.jks" keystorePass="tompass" keyPass="tompass" truststoreFile="idp-ssl-trust.jks" truststorePass="ispass" />
    Now start Tomcat, and check that the IdP is live by opening the STS WSDL in a web browser: 'https://localhost:8443/fediz-idp-sts/REALMA/STSServiceTransport?wsdl'

    For a more thorough test, enter the following in a web browser - you should be directed to the URL for the service application (404, as we have not yet configured it):

    https://localhost:8443/fediz-idp/federation?wa=wsignin1.0&wreply=http%3A%2%2Flocalhost%3A8080%2Fwsfedhelloworld%2Fsecureservlet%2Ffed&wtrealm=urn%3Aorg%3Aapache%3Acxf%3Afediz%3Afedizhelloworld

    2) Deploying the simpleWebapp in Apache Tomcat

    To deploy the service to Tomcat:
    • Copy ${fediz.home}/examples/samplekeys/rp-ssl-server.jks and ${fediz.home}/examples/samplekeys/ststrust.jks to ${catalina.home}.
    • Copy ${fediz.home}/examples/simpleWebapp/src/main/config/fediz_config.xml to ${catalina.home}/conf/
    • Edit ${catalina.home}/conf/fediz_config.xml and replace '9443' with '8443'.
    • Do a "mvn clean install" in ${fediz.home}/examples/simpleWebapp
    • Copy ${fediz.home}/examples/simpleWebapp/target/fedizhelloworld.war to ${catalina.home}/webapps.
    3) Testing the service

    To test the service navigate to:
    • https://localhost:8443/fedizhelloworld/  (this is not secured) 
    • https://localhost:8443/fedizhelloworld/secure/fedservlet
    With the latter URL, the browser is redirected to the IDP (select realm "A") and is prompted for a username and password. Enter "alice/ecila" or "bob/bob" or "ted/det" to test the various roles that are associated with these username/password pairs.
    Categories: Colm O hEigeartaigh

    Apache CXF Fediz 1.2.0 tutorial - overview

    Thu, 05/28/2015 - 17:59
    Apache CXF Fediz 1.2.0 has been released. Fediz is a subproject of the Apache CXF web services stack. It is an implementation of the WS-Federation Passive Requestor Profile for SSO that supports Claims Based Access Control. In laymans terms, Fediz allows you to implement Single Sign On (SSO) for your web application, by redirecting the client browser to an Identity Provider (IdP), where the client is authenticated and redirected back to the application. Fediz consists of a number of container-specific plugins (Tomcat, Jetty, Spring Security, Websphere, etc.) as well as an IdP which bundles the CXF Security Token Service (STS) to issue SAML Tokens.

    This is an overview of a planned series of articles on the new features that are available in Fediz 1.2.0, which is a new major release of the project. Subsequent articles will go into more detail on the new features, which are as follows:
    • Dependency update to use CXF 3.0.x (3.0.4).
    • A new container-independent CXF-based plugin is available.
    • Logout Support has been added to the plugins and IdP
    • A new REST API is available for configuring the IdP
    • Support for authenticating to the IdP using Kerberos has been added
    • Support for authenticating to the IdP using a client certificate has been added
    • It is now possible to use the IdP as an identity broker with a SAML SSO IdP
    • Metadata support has been added for the plugins and IdP
    Categories: Colm O hEigeartaigh

    SAML SSO RP Metadata support in Apache CXF

    Thu, 05/28/2015 - 17:28
    Apache CXF provides comprehensive support for SSO using the SAML Web SSO profile for CXF-based JAX-RS services. In Apache CXF 3.1.0 (and 3.0.5), a new Metadata service is available to allow for the publishing of SAML SSO Metadata for a given service.

    The MetadataService class is available on a "metadata" path and provides a single @GET method that returns the service metadata in XML format. It has the following properties which should be configured:
    • String serviceAddress - The URL of the service
    • String assertionConsumerServiceAddress - The URL of the RACS. If it is co-located with the service, then it can be the same URL as for the serviceAddress.
    • String logoutServiceAddress - The URL of the logout service (if available).
    • boolean addEndpointAddressToContext - Whether to add the full endpoint address to the values configured above. The default is false.
    In addition, the MetadataService extends the AbstractSSOSpHandler, which contains various properties that are required to sign the metadata (keystore alias, crypto properties file which references the keystore, etc.). A sample spring-based configuration for the MetadataService is available in the CXF system tests here. Here is the sample output when accessed via a web brower:


    Categories: Colm O hEigeartaigh

    Apache CXF 3.1.0 released

    Tue, 05/26/2015 - 16:04
    Apache CXF 3.1.0 has been released and is available for download. The migration guide for CXF 3.1.x is available here. The main (non-security) features of CXF 3.1.0 are as follows:
    • Java 6 is no longer supported.
    • Jetty 9 is now supported. Support for Jetty 7 has been dropped.
    • A new Metrics feature for collecting metrics about CXF services is available. 
    • A new Throttling feature is available for easily throttling CXF services.
    • A new Logging feature is available that is more powerful than the existing logging functionality.
    The security-specific changes and features are as follows:
    • CXF 3.1.0 picks up a new major release of WSS4J (2.1.0) and OpenSAML (3.1.0). Please see a recent post on WSS4J 2.1.0 for some migration notes if you are using WS-Security or SAML with CXF.
    • The STS now signs issued SAML tokens by default using RSA-SHA256 (previously RSA-SHA1).
    • Some security configuration tags have been renamed from "ws-security.*" to "security.*", as they are now shared with the XML Security JAX-RS module. The old tags will continue to work as before however without any change. See the Security Configuration page for more information.
    • The SAML/XACML functionality previously available in the cxf-rt-security module is now in a new cxf-rt-security-saml module.
    • A new Metadata service for SAML SSO is available. More on this in a future blog post.
    • It is now possible to "plug in" custom security policy validators for WS-Security in CXF, if you want to change the default validation logic. See here for a test that shows how to do this.
    Categories: Colm O hEigeartaigh

    Apache WSS4J 2.0.4 released

    Fri, 05/15/2015 - 16:24
    In addition to the new major release of Apache WSS4J (2.1.0), there is a new bug fix release available - Apache WSS4J 2.0.4. Here are the most important bugs that were fixed in this release:
    • We now support the InclusiveC14N policy.
    • We can enforce that a Timestamp has an "Expires" Element via configuration, if desired.
    • There is a slight modification to how we cache signed Timestamps, to allow for the scenario of two Signatures in a security header that sign the same Timestamp, but with different keys.
    • The policy layer now allows a SupportingToken policy to have more than one token.
    • A bug has been fixed in the MerlinDevice crypto provider, which is designed to work with smartcards.
    • A bug has been fixed in terms of using the correct JCE provider for encryption/decryption.
    Categories: Colm O hEigeartaigh

    Apache WSS4J 2.1.0 released

    Fri, 05/15/2015 - 16:23
    A new major release of Apache WSS4J, 2.1.0, has been released. The previous major release of almost a year ago, Apache WSS4J 2.0.0, had a lot of substantial changes (see the migration guide), such as a new set of maven modules, a new streaming implementation, changes to configuration tags, package changes for CallbackHandlers, etc. In contrast, WSS4J 2.1.0 has a much smaller set of changes, and users should be able to upgrade with very few changes (if at all). This post briefly covers the new features and migration issues for WSS4J 2.1.0.

    Here are the new features of WSS4J 2.1.0:
    • JDK7 minimum requirement: WSS4J 2.1.0 requires at least JDK7. The project source has also been updated to make use of some of the new features of JDK7, such as try-with-resources, etc.
    • OpenSAML 3.x support: WSS4J 2.1.0 upgrades from OpenSAML 2.x to 3.x (currently 3.1.0). This is an important upgrade, as OpenSAML 2.x is not currently supported.
    • Extensive code refactoring. A lot of work was done to make the retrieval of security results easier and faster.

    Here are the migration issues in WSS4J 2.1.0:
    • Due to the OpenSAML 3.x upgrade, you will need to make a small change in your SAML CallbackHandlers, if you are specifying the "Version". In WSS4J 2.0.x, you could specify the SAML Version by passing a "org.opensaml.common.SAMLVersion" instance through to the SAMLCallback.setSamlVersion(...) method. The "org.opensaml.common" package is removed in OpenSAML 3.x. Instead, a new Version bean is provided in WSS4J 2.1.0, that can be passed to the setSamlVersion method on SAMLCallback as before. See here for an example.
    • The Xerces and xml-apis dependencies in the DOM code of Apache WSS4J 2.1.0 have been removed (previously they were at "provided" scope).
    • If you have a custom Processor instance to process a token in the security header in some custom way, you must add the WSSecurityEngineResult that is generated by the processing, to the WSDocInfo Object via the "addResult" method. Otherwise, it will not be available when security results are retrieved and processed.


    Categories: Colm O hEigeartaigh

    Apache Santuario - XML Security for Java 2.0.4 released

    Wed, 04/22/2015 - 15:09
    Apache Santuario - XML Security for Java 2.0.4 has been released. The issues fixed are available here. Perhaps the most significant issue fixed is an interop issue which emerged when XML Security is used with OpenSAML (see the Apache CXF JIRA where this was raised).
    Categories: Colm O hEigeartaigh

    Vulnerability testing of Apache CXF based web services

    Mon, 04/13/2015 - 16:21
    A number of automated tools can be used to conduct vulnerability or penetration testing of web services. In this article, we will take a look at using WS-Attacker to attack Apache CXF based web service endpoints. WS-Attacker is a useful tool based on SOAP-UI and developed by the Chair of Network and Data Security, Ruhr University Bochum (http://nds.rub.de/) and 3curity GmbH (http://3curity.de/). As an indication of how useful this tool is, it has uncovered a SOAP Action Spoofing vulnerability in older versions of CXF (see here). In this testing scenario, WS-Attacker 1.4-SNAPSHOT was used to test web services using Apache CXF 3.0.4. Apache CXF 3.0.4 is immune to all of the attacks described in this article (as can be seen from the "green" status in the screenshots).

    1) SOAPAction Spoofing attacks

    A SOAPAction spoofing attack is where the attacker will attempt to fool the service by "spoofing" the SOAPAction header to execute another operation. To test this I created a CXF based SOAP 1.1 endpoint which uses the action "soapAction="http://doubleit/DoubleIt"". I then loaded the WSDL into WS-Attacker, and selected the SOAPAction spoofing plugin, selecting a manual SOAP Action. Here is the result:


    2) WS-Addressing Spoofing attacks

    A WS-Addressing Spoofing attack involves sending an address in the WS-Addressing ReplyTo/To/FaultTo header that is not understood or known by the service, but to which the service redirects the message anyway. To guard against this attack in Apache CXF it is required to ensure that the WS-Addressing headers should be signed. As a sanity test, I added an endpoint where WS-Addressing is not configured, and the tests fail as expected:



    3) XML Signature wrapping attacks

    XML Signature allows you to sign various parts of a SOAP request, where the parts in question are referenced via an "Id". An attacker can leverage various "wrapping" based attacks to try to fool the resolution of a signed Element via its "Id". So for example, an attacker could modify the signed SOAP Body of a valid request (thus causing signature validation to fail), and put the original signed SOAP Body somewhere else in the request. If the signature validation code only picks up the Element that has been moved, then signature validation will pass even though the SOAP Body has been modified.

    For this test I created a number of endpoints that are secured using WS-SecurityPolicy. I captured a successful signed request from a unit test and loaded it into WS-Attacker, and ran the Signature wrapping attack plugin. Here is the result:


    4) Denial of Service attacks

    A Denial of Service attack is where an attacker attempts to crash or dramatically slow down a service by flooding it with data, or crafting a message in such a way as to cause parsing to crash or hang. An example might be to create an XML structure with a huge amount of Attributes or Elements, that would cause an out of memory error. WS-Attacker comes with a range of different attacks in this area. Here are the results of all of the DoS attacks against a plain CXF SOAP service (apart from the SOAP Array attack, as the service doesn't accept a SOAP array):


    Categories: Colm O hEigeartaigh

    New Apache WSS4J and CXF releases

    Fri, 02/20/2015 - 17:37
    Apache WSS4J 2.0.3 and 1.6.18 have been released. Both releases contain a number of fixes in relation to validating SAML tokens, as covered earlier. In addition, Apache WSS4J 2.0.3 has unified security error messages to prevent some attacks (see here for more information). Apache CXF 3.0.4 and 2.7.15 have also been released, both of which pick up the recent WSS4J releases.
    Categories: Colm O hEigeartaigh

    Unified security error messages in Apache WSS4J and CXF

    Mon, 02/16/2015 - 17:59
    When Apache WSS4J encounters a error on processing a secured SOAP message it throws an exception. This could be a configuration error, an invalid Signature, incorrect UsernameToken credentials, etc. The SOAP stack in question, Apache CXF for the purposes of this post, then converts the exception into a SOAP Fault and returns it to the client. However the SOAP stack must take care not to leak information (e.g. internal configuration details) to an attacker. This post looks at some changes that are coming in WSS4J and CXF in this area.

    The later releases of Apache CXF 2.7.x map the WSS4J exception message to one of the standard error QNames defined in the SOAP Message Security Profile 1.1 specification. One exception is if a "replay" error occurred, such as if a UsernameToken nonce is re-used. This type of error is commonly seen in testing scenarios, when messages are replayed, and returning the original error aids in figuring out what is going wrong. Apache CXF 3.0.0 -> 3.0.3 extends this functionality a bit by adding a new configuration option:
    • ws-security.return.security.error - Whether to return the security error message to the client, and not one of the default error QNames. Default is "false".
    However, even returning one of the standard security error QNames can provide an "oracle" for certain types of attacks. For example, Apache WSS4J recently released a security advisory for an attack that works if an attacker can distinguish whether the decryption of an EncryptedKey or EncryptedData structure failed. There are also attacks on data encrypted via a cipher block chaining (CBC) mode, that only require the knowledge about whether the specific decryption failed.

    Therefore from Apache WSS4J 2.0.3 onwards (and CXF 3.0.4 onwards) a single error fault message ("A security error was encountered when verifying the message") and code ("http://ws.apache.org/wss4j", "SecurityError") is returned on a security processing error. It is still possible to set "ws-security.return.security.error" to "true" to return the underlying security error to aid in testing etc.
    Categories: Colm O hEigeartaigh

    Pages