Monday, December 22, 2014

New SSL/TLS vulnerabilities in Apache CXF

Apache CXF 3.0.3 and 2.7.14 have been released. Both of these releases contain fixes for two new SSL/TLS security advisories:
  • Note on CVE-2014-3566: This is not an advisory per se, but rather a note on an advisory. CVE-2014-3566 (aka "POODLE") is a well publicised attack which forces a TLS connection to downgrade to use SSL 3.0, which in turn is vulnerable to a padding oracle attack. Apache CXF 3.0.3 and 2.7.14 disable SSL 3.0 support by default for both clients, as well as servers configured using CXF's special support for Jetty. In addition, it is now possible to explicitly exclude protocols, see here for more information.
  • CVE-2014-3577: Apache CXF is vulnerable to a possible SSL hostname verification bypass, due to a flaw in comparing the server hostname to the domain name in the Subject's DN field. A Man In The Middle attack can exploit this vulnerability by using a specially crafted Subject DN to spoof a valid certificate.
If you are using TLS with Apache CXF then please upgrade to the latest releases.

Tuesday, December 2, 2014

XML Security using Apache Camel

I have previously covered how to use Apache Santuario to sign and encrypt XML, using both the DOM and StAX based APIs available in the 2.0.x releases. An alternative to using Apache Santuario directly to sign/encrypt XML, is to use the XML Security component or data format of Apache Camel. There are two obvious reasons to use Camel that immediately spring to mind. Firstly it allows you to configure XML Signature/Encryption without writing any code (e.g. by configuring the components in Spring). Secondly it allows you to take advantage of the power and flexibility of Apache Camel to integrate with a wide variety of components.

I have created a github project with two (almost identical) tests to show how to use XML Signature and Encryption in Apache Camel:
Both tests start routes which read in XML documents stored in src/test/resources/data using the Camel File component. The part of the documents which contain credit card information is then signed/encrypted, and the resulting file placed in the target/(encrypted/signed)-data folder. A second route reads files in from this folder, decrypts/verifies the file and then places it in the target/(decrypted/verified)-data folder.

The encryption configuration file is available here, and the signature configuration file is here. One difference you may notice is that encryption is configured using a "marshal/unmarshal" tag and then "secureXML", whereas for signature you can use a standard Camel "To" statement, e.g. "
<to uri="xmlsecurity:sign://enveloped?keyAccessor...". This is due to the fact that XML Encryption is implemented in Camel as a data format, whereas XML Signature is implemented as a component.

Both tests also use the Camel Jasypt component to avoid hard-coding plaintext passwords in the spring configuration files. The keystore and private key passwords and stored encrypted in a special passwords file. The master secret used to decrypt the passwords is retrieved via a system property (set in the pom.xml as part of the tests).

The testcase relies on a SNAPSHOT version of Apache Camel for now (2.15-SNAPSHOT) due to a number of fixes I added. Firstly, the DefaultKeySelector used to retrieve keys for signature did not previously support taking a Camel
keyStoreParameters Object. Secondly, the DefaultKeySelector did not support working with the Camel Jasypt component to encrypt the keystore password.  Thirdly, it wasn't possible to load a Public Key from a PrivateKeyEntry in a Keystore for XML Signature. Fourthly, the XML Encryption data format did not support embedding the KeyValue of the Public Key used to encrypt the session key in the EncryptedKey structure.

Thursday, November 13, 2014

Apache Syncope 1.2 tutorial - part IV

This is the fourth and final post in a series of articles on Apache Syncope 1.2. The previous tutorial looked at some new features relating to the Schema in Apache Syncope 1.2. This post will look at the REST API of Syncope and how it can be queried. We will also look at the new JAAS LoginModule for Apache Syncope that has been developed in Apache Karaf.

1) REST API of Apache Syncope

Apache Syncope features a rich REST API powered by Apache CXF. It is available via the URI "/syncope/rest/". Note that Apache Syncope 1.1 featured two REST APIs, one powered by Spring and another by Apache CXF, which was a refactoring of the former based on RESTful best practices. The Spring based API has been dropped in Apache Syncope 1.2, and only the CXF based API is now available via the "/syncope/rest" URI. Here are some example REST GET URIs for the "User" service in Syncope 1.2, that you can try out in a browser:
  • syncope/rest/users.json - get a list of all users in JSON format
  • syncope/rest/users - get a list of all users in an XML format
  • syncope/rest/users/self - get the authenticated user
Apache Syncope 1.2 uses the WADL generation capabilities of Apache CXF to expose the REST API as a WADL document. This can be accessed by adding "?_wadl" to the URI, for example "syncope/rest/?_wadl":


This document can be converted to HTML, and is available via the URI "/syncope/rest/doc/". Another new feature of the REST API in Apache Syncope 1.2 is support for FIQL. This allows you to easily search for users or roles matching a certain expression. For example:
  • syncope/rest/users/search?_s=lastLoginDate=ge=2014-11-13 - Search for the users who have logged in since 20014/11/13.
  • syncope/rest/users/search?_s=surname==smith - Search for the users with surname 'smith'.

2) JAAS LoginModule for Syncope

In a previous blog post written about the REST API of Apache Syncope, I gave detailed of a github project with some CXF based testcases. The tests showed how a CXF service could use Apache Syncope to authenticate a WS-Security UsernameToken presented by a client (as well as HTTP/BA). In addition, some other tests asked Syncope for the roles associated with the user, and enforced access to the service depending on the result. This github project has now moved to a new location here, and the tests have been updated to use the correct URLs for Apache Syncope 1.2.

In addition, a new test is added that shows how to use the new JAAS LoginModule for Syncope for authentication and authorization. The SyncopeLoginModule was developed for use in Apache Karaf, but can be used in others containers as well. In the testcase, the CXF JAASAuthenticationFeature is set on the service bus, which selects the "karaf" JAAS realm by default. The JAAS configuration file for the test is simply:

karaf {
    org.apache.karaf.jaas.modules.syncope.SyncopeLoginModule required
    debug="true"
    address="http://localhost:8080/syncope/rest";
};

See Jean-Baptiste Onofré's blog for a further description of how to set up and test the SyncopeLoginModule.

Monday, November 10, 2014

Apache Syncope 1.2 tutorial - part III

This is the third in a series of articles on the new features of Apache Syncope 1.2. The first article covered installing Syncope using the new UI installer. The second article demonstrated some new features of Apache Syncope 1.2 when working with backend resources, namely the ability to synchronize and propagate encrypted passwords. This post focuses on some new features associated with schemas in Syncope 1.2.

Apache Syncope uses the concept of a schema to define attributes for User, Roles and Memberships (the relationship of a User with a Role). You can define the attribute name, the type, whether it is multi-valued, whether it is unique or read-only, whether it is stored internally or remotely, etc. There are three new interesting features in Syncope 1.2 in the area of Schemas:
  • Configuration Schema: The Configuration parameters are now covered by the Schema. You can add new attributes for the Configuration section in the Schema section.
  • Encrypted Schema attributes: A new "Encrypted" attribute type is available. This will ensure that Syncope always keeps the attribute value encrypted with the specified key.
  • Binary Schema attributes: A new "Binary" attribute type is available.
We will now focus on this latter feature. We will show how to use binary attributes with two examples. Start Apache Syncope + set up the LDAP Connector + Resource as covered in the first two tutorials.

1) Import X.509 Certificates into Syncope

The first use-case for binary schema attributes is to allow the synchronization of X.509 Certificates into Syncope from a backend resource. Go to the "Schema" tab, and create a new "User" attribute called "certificate" of type "Binary", and with mime type "application/x-x509-user-cert":



Next, go into the LDAP Resource configuration and add a new user mapping from the "certificate" attribute of the "UserSchema" to the LDAP "userCertificate" attribute. Now make sure that you have a user in your LDAP backend with a "userCertificate" attribute defined as follows:



Finally, run the synchronization task in Syncope. The user now has the certificate added as an attribute, which can be downloaded or else retrieved via the REST API:


2) Import images into Syncope

Another common use-case for binary attributes is to import images into Syncope. Create a new binary User attribute in the Schema called "image" of type "image/jpeg", and a new User mapping for the LDAP Connector mapping it to the LDAP "jpegPhoto" attribute. Assuming that a user in the LDAP backend has such an attribute defined, the newly synchronized User will look like this:




Friday, November 7, 2014

Apache Syncope 1.2 tutorial - part II

The previous tutorial on the new features of Apache Syncope 1.2 showed how to use the new UI installer to deploy Apache Syncope to Apache Tomcat, using MySQL for persistent storage. Last year we covered how to import users (and roles) from backend resources such as a database or a directory. An important new feature of Apache Syncope 1.2 is the ability to import non-cleartext passwords into Syncope when synchronizing from backend resources (and also the ability to propagate non-cleartext passwords to resources). The default behaviour is to hash the password according to the global configuration parameter 'password.cipher.algorithm' (defaults to SHA-1). This is problematic if the password is already hashed, as user authentication via the Syncope REST API will then fail.

1) Create policies in Apache Syncope

The first step is to start Apache Syncope and to create some policies for account and password creation, as well as synchronization. Start Syncope and go to the Configuration tab. Select "Policies" and create new "global" policy types for both "Account", "Password" and "Synchronization", with some sensible default values.

2) Synchronizing non-cleartext passwords from Apache Derby.

This is an update from the previous blog entry on importing users from Apache Derby using Syncope 1.1. Follow step 1 "Creating a Schema attribute" and step 2 "Apache Derby" in the previous blog. However, in section 2.b, rather than adding users with plaintext passwords, use the following user value instead when creating a table:

INSERT INTO USERS VALUES('dave', '8eec7bc461808e0b8a28783d0bec1a3a22eb0821', 'true', 'yellow');

Instead of using a plaintext password value, the second field is the SHA-1 encoded value of "security". In section 3.a "Define a Connector", it is necessary to change the "Password cipher algorithm" value from "CLEARTEXT" to "SHA1". In step 3.b "Define a Resource", it is necessary to specify an external attribute for the Username mapping of "NAME". Finally, in step 3.c "Create a synchronization task", use the "DBSyncPasswordActions" action class. This class treats the password retrieved from the table as encoded according to the "Password cipher algorithm" parameter of the Connector ("SHA1" in this case), and to store it directly in Syncope without subsequently hashing it again, which is what would happen for the plaintext case. Note that the presumption is that the (hashed) password is HEX encoded in the table.

After executing the synchronization task, then start a browser and navigate to "http://localhost:8080/syncope/rest/users/self", logging on as "dave" and "security".



3) Synchronizing non-cleartext passwords from Apache DS.

This is an update from the previous blog entry on importing users and roles from an LDAP backend such as Apache DS into Apache Syncope 1.1. Follow the first step in the previous tutorial to set up Apache DS and import users and groups. Add some users, e.g. "colm", this time with a SHA-256 encoded password. Importing users with encoded passwords from LDAP is a bit more sophisticated than the DB case above, because individual users can have different digest algorithms with the LDAP synchronization case, whereas all users must have the same digest algorithm for the DB synchronization case.

Start up Syncope, and follow the steps given in the previous tutorial to create a new connector and resource. The only difference with Syncope 1.2 is that you need to specify the external attribute for both the Username and Rolename mapping ("cn" in both cases for this example). Finally, create the Synchronization task as per the previous tutorial. However this time add both the LDAPPasswordSyncActions and LDAPMembershipSyncActions classes as "Actions classes". Finally execute the task, and check to see if the users + roles were imported successfully into Syncope. You can then log on via
"http://localhost:8080/syncope/rest/users/self" using any of the users imported from Apache DS, regardless of the internal cipher algorithm that was used.

Thursday, November 6, 2014

Apache Syncope 1.2 tutorial - part I

Apache Syncope is a powerful and flexible open source tool to manage and orchestrate user identities for the enterprise. Last year, I wrote a series of four tutorials on Apache Syncope. The first covered how to create an Apache Syncope project, how to set up a MySQL database for internal storage, and how to deploy Apache Syncope to Apache Tomcat. The second covered how to import user identities and attributes from a database (Apache Derby) into Syncope. The third covered how to import users and roles from an LDAP backend (Apache DS) into Syncope. Finally, the fourth tutorial covered the REST API of Apache Syncope, as well as a set of Apache CXF-based testcases to demonstrate how to use the REST API of Apache Syncope for authentication and authorization.

This will be the first post in a new set of tutorials for Apache Syncope, with a focus on updating the previous set of tutorials (based on Syncope 1.1) with some updated features and new functionality that is available in the recently released 1.2.0 release. In this post we will cover how to use the new UI installer for creating a Apache Syncope project and deploying it to a container. This tutorial can be viewed as a more user-friendly alternative to the first tutorial of the previous series. Please also see the Syncope documentation on using the installer.

1) Set up a database for Internal Storage

The first step in setting up a standalone deployment of Apache Syncope is to decide what database to use for Internal Storage. Apache Syncope persists internal storage to a database via Apache OpenJPA. In this article we will set up MySQL, but see here for more information on using PostgreSQL, Oracle, etc. Install MySQL in $SQL_HOME and create a new user for Apache Syncope. We will create a new user "syncope_user" with password "syncope_pass". Start MySQL and create a new Syncope database:

  • Start: sudo $SQL_HOME/bin/mysqld_safe --user=mysql
  • Log on: $SQL_HOME/bin/mysql -u syncope_user -p
  • Create a Syncope database: create database syncope; 

2) Set up a container to host Apache Syncope

The next step is to figure out in what container to deploy Syncope to. In this demo we will use Apache Tomcat, but see here for more information about installing Syncope in other containers. Install Apache Tomcat to $CATALINA_HOME. Now we will add a datasource for internal storage in Tomcat's 'conf/context.xml'. When Syncope does not find a datasource called 'jdbc/syncopeDataSource', it will connect to internal storage by instantiating a new connection per request, which carries a performance penalty. Add the following to 'conf/context.xml':

<Resource name="jdbc/syncopeDataSource" auth="Container"
    type="javax.sql.DataSource"
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    testWhileIdle="true" testOnBorrow="true" testOnReturn="true"
    validationQuery="SELECT 1" validationInterval="30000"
    maxActive="50" minIdle="2" maxWait="10000" initialSize="2"
    removeAbandonedTimeout="20000" removeAbandoned="true"
    logAbandoned="true" suspectTimeout="20000"
    timeBetweenEvictionRunsMillis="5000" minEvictableIdleTimeMillis="5000"
    jdbcInterceptors="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;
    org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"
    username="syncope_user" password="syncope_pass"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/syncope?characterEncoding=UTF-8"/>

Uncomment the "<Manager pathname="" />" configuration in context.xml as well. The next step is to enable a way to deploy applications to Tomcat using the Manager app. Edit 'conf/tomcat-users.xml' and add the following:

<role rolename="manager-script"/>
<user username="manager" password="s3cret" roles="manager-script"/>

Next, download the JDBC driver jar for MySQL and put it in Tomcat's 'lib' directory. As we will be configuring a connector for a Derby resource in a future tutorial, also download the JDBC driver jar for Apache Derby and put it in Tomcat's 'lib' directory as well.

3) Run the Installer

Download and run the installer via 'java -jar syncope-installer-1.2.0-uber.jar'. You need to enter some straightforward values such as the installation path of the project, the Apache Maven home directory, the groupId/artifactId of the project, the directories where logs/bundles/configuration are stored.


Next, select "MySQL" as the database technology from the list, and give "syncope_user" and "syncope_pass" as the username + password, or whatever you have configured earlier when setting up MySQL. Select "Tomcat" as the application server (make sure the 'syncopeDataSource' is checked), and enter values for the address, port, manager username and password:


The installer will then create a Apache Syncope project + deploy it to Tomcat:


When the installer has finished, startup a browser and go to "localhost:8080/syncope-console", logging in as "admin/password". You should see the following:

Monday, November 3, 2014

Security semantics of SAML SubjectConfirmation methods in Apache WSS4J/CXF

A recent blog post covered two new security advisories issued for Apache CXF in relation to SAML tokens. In particular, one advisory dealt with the enforcement of the security semantics of SAML SubjectConfirmation methods when used with the TransportBinding:
There are different security requirements associated with SAML
SubjectConfirmation methods. These security requirements are not properly enforced in Apache CXF when used with the TransportBinding, leaving endpoints that rely on SAML for authentication vulnerable to types of spoofing attacks.
In this post I will recap the security requirements that are associated with SAML SubjectConfirmation methods in the latest CXF releases:
  • Holder-of-Key: If the subject confirmation method is "holder-of-key", there must be some proof-of-possession of the key associated with the subject of the assertion. CXF will enforce that either the key was used to sign some portion of the SOAP request, or alternatively the subject credential of the SAML Assertion must match a client certificate credential when TLS with client authentiction is used.
  • Sender-Vouches: If the subject confirmation method is "sender-vouches", then CXF will enforce that the SAML Assertion and SOAP Body are signed by the same signature. Alternatively, it will check that TLS with client authentication is used.
  • Bearer: The SAML Assertion must be signed (with an internal XML Signature) by default. This can be configured in the latest WSS4J releases.
In addition, the SamlAssertionValidator in WSS4J now enforces that at least one of the standard SubjectConfirmation methods (as listed above) is present. It is also possible to specify a given SubjectConfirmation method that is required.

Friday, October 31, 2014

Using Apache JMeter to load test Apache CXF endpoints

Apache JMeter is a graphical tool that can be used to load-test your web applications. I created a new project in my github repo that creates a web application with a number of CXF endpoints, as well as a JMeter configuration file that can be used to load test the endpoints. The benefit of doing this kind of testing is to figure out how responsive various (security) protocols might be under load. In addition, the project uncovered a couple of threading issues surrounding policy handling, which were fixed by Dan Kulp in CXF 3.0.1.

The endpoints that are exposed in the application are:
  • /doubleit/services/doubleitnosecurity - No security at all. This can be used to test throughput over plaintext and TLS.
  • /doubleit/services/doubleittransport - This uses a Transport binding with a UsernameToken supporting token. The UsernameToken is just validated by a simple CallbackHandler on the service side. 
  • /doubleit/services/doubleitsymmetric - This uses a Symmetric binding with a UsernameToken supporting token. The UsernameToken is just validated by a simple CallbackHandler on the service side. 
  • /doubleit/services/doubleitsymmetricstreaming - This is the same as per the symmetric case above, except that it uses the new streaming WS-Security implementation available in Apache CXF 3.0.0. 
  • /doubleit/services/doubleitasymmetric - This uses a Asymmetric binding. Authentication is established by a certificate chain. 
  • /doubleit/services/doubleitasymmetricstreaming - Same as for the asymmetric case above, except that it uses the new streaming WS-Security implementation available in Apache CXF 3.0.0. 
Simply build the project with "mvn clean install" and drop the resulting .war file into your container (e.g. Apache Tomcat). Then start up JMeter + import the configuration file and run the tests.

Friday, October 24, 2014

Two new security advisories for Apache CXF

Two new security advisories have been released for Apache CXF, please see the CXF security advisories page for the details:
  • CVE-2014-3623: Apache CXF does not properly enforce the security semantics of SAML SubjectConfirmation methods when used with the TransportBinding
  • CVE-2014-3584: Apache CXF JAX-RS SAML handling is vulnerable to a Denial of Service (DoS) attack
If you are using SAML SSO or else SAML tokens with the WS-SecurityPolicy Transport binding you should upgrade to either CXF 2.7.13 or 3.0.2.

Thursday, October 23, 2014

Apache CXF Authentication and Authorization test-cases IV

This is the fourth in a series of posts on authentication and authorization test-cases for web services using Apache CXF. The first focused on different ways to authenticate and authorize UsernameTokens for JAX-WS services. The second looked at more advanced examples such as using Kerberos, WS-Trust, XACML, etc. The third looked at different ways of achieving SSO in CXF for both JAX-WS and JAX-RS services. This post gives some examples of authenticating and authorizing JAX-RS services in Apache CXF. I also included the SSO examples relevant to JAX-RS from the previous post. The projects are:
  • cxf-jaxrs-xmlsecurity: This project shows how to use XML Signature (and Encryption) to secure JAX-RS services. In particular, see the AuthenticationTest.
  • cxf-jaxrs-sts: This project demonstrates how to use HTTP/BA for authentication for JAX-RS, where the credentials are dispatched as a UsernameToken are dispatched to an STS instance for authentication. In addition, the project shows how to authorize the request by asking the STS for a SAML Token containing the roles of the user.
  • cxf-kerberos: This project (covered previously for JAX-WS) has been updated with a test that shows how to use Kerberos with JAX-RS.
  • cxf-saml-sso: This project shows how to leverage SAML SSO with Apache CXF to achieve SSO for a JAX-RS service. CXF supports the POST + redirect bindings of SAML SSO for JAX-RS endpoints. As part of this demo, a mock CXF-based IdP is provided which authenticates a client using HTTP/BA and issues a SAML token using the CXF STS. Authorization is also demonstrated using roles embedded in the issued SAML token. 
  • cxf-fediz-federation-sso: This project shows how to use the new CXF plugin of Apache Fediz 1.2.0 to authenticate and authorize clients of a JAX-RS service using WS-Federation. This feature will be documented more extensively at a future date, and is considered experimental for now. Please play around with it and provide feedback to the CXF users list.

Wednesday, October 22, 2014

Apache CXF Fediz 1.1.2 released

Apache CXF Fediz 1.1.2 has been released. Apache CXF Fediz is a Single Sign-On (SSO) solution based on the WS-Federation Passive Requestor Profile. It consists of an Identity Provider (IdP) which leverages the Apache CXF STS to issue tokens, as well as a number of container-specific plugins (Jetty, Tomcat, Spring, etc.) to enable SSO for web applications. The issues fixed in the new release include an upgrade to CXF 2.7.13, support for claims mapping in the STS, kerberos authentication support in the IdP, amongst other fixes.

Tuesday, October 21, 2014

Kerberos Credential Delegation support in Apache CXF

Apache CXF provides full support for integrating Kerberos with JAX-WS and JAX-RS services. A previous tutorial (here and here) described how to set up Kerberos with WS-Security in CXF, where the client obtains a Kerberos service ticket and encodes it in the security header of the request, and where it is validated in turn by the service. In this post we will discuss support for kerberos credential delegation for JAX-WS clients and services in Apache CXF. For more information on using kerberos with JAX-RS please consult the CXF documentation.

1) Kerberos Client Configuration

CXF provides a number of JAX-WS properties that can be used to configure Kerberos on the client side (documented here under "Kerberos Configuration Tags"). Essentially there are two different ways of doing it. The client must explicitly allow kerberos credential delegation by setting a property.

1.1) Create and configure a KerberosClient Object directly

The KerberosClient in the CXF WS-Security runtime module is used to retrieve a kerberos ticket. It can be configured by setting various properties and then referenced via the JAX-WS property:
  • ws-security.kerberos.client - A reference to the KerberosClient class used to obtain a service ticket.
The "requestCredentialDelegation" property of the KerberosClient must be set to "true" to allow credential delegation. Here is an example in Spring:

<bean class="org.apache.cxf.ws.security.kerberos.KerberosClient" id="kerberosClient">
        <constructor-arg ref="cxf"/>
        <property name="contextName" value="bob"/>
        <property name="serviceName" value="bob@service.ws.apache.org"/>
        <property name="requestCredentialDelegation" value="true"/>
</bean>

<jaxws:client name="{service}port" createdFromAPI="true">
        <jaxws:properties>
            <entry key="ws-security.kerberos.client" value-ref="kerberosClient"/>
        </jaxws:properties>
</jaxws:client>

1.2) Use JAX-WS properties to configure Kerberos

Rather than use the KerberosClient above, it is possible to configure Kerberos via JAX-WS properties:
  • ws-security.kerberos.jaas.context - The JAAS Context name to use for Kerberos.
  • ws-security.kerberos.spn - The Kerberos Service Provider Name (spn) to use.
  • ws-security.kerberos.is.username.in.servicename.form - Whether the Kerberos username is in servicename form or not.
  • ws-security.kerberos.use.credential.delegation - Whether to use credential delegation or not in the KerberosClient.
  • ws-security.kerberos.request.credential.delegation - Whether to request credential delegation or not in the KerberosClient.
The latter property must be set to "true" on the client side to allow kerberos credential delegation.

2) Kerberos Service Configuration

A JAX-WS service validates a kerberos ticket received in the security header of a request via a KerberosTokenValidator. Here is an example:

<bean id="kerberosValidator"
           class="org.apache.wss4j.dom.validate.KerberosTokenValidator">
        <property name="contextName" value="bob"/>
        <property name="serviceName" value="bob@service.ws.apache.org"/>
</bean>
<jaxws:endpoint ...>
        <jaxws:properties>
            <entry key="ws-security.bst.validator" value-ref="kerberosValidator"/>
        </jaxws:properties>
</jaxws:endpoint>
   
3) Using Kerberos Credential Delegation

After a service has validated a kerberos token sent by the client, it can obtain another kerberos token "on behalf of" the client, assuming the client enabled credential delegation in the first place. To use the client credential for delegation the "useDelegatedCredential" property of the KerberosClient must be set to "true" (see here), or else the JAX-WS property "ws-security.kerberos.use.credential.delegation" must be set to "true" if not configuring Kerberos via the KerberosClient Object.

To see how a concrete use-case for this functionality, take a look at the KerberosDelegationTokenTest in the CXF STS advanced systests. Here we have a backend service which requires a SAML Token issued by an STS. However, the clients only know how to obtain a Kerberos token. So we have an intermediary service which requires a Kerberos token. The clients enable credential delegation + send a ticket to the Intermediary. The Intermediary validates the ticket, then uses it to obtain a Kerberos token "OnBehalfOf" the client, which in turn is used to authenticate to the STS + retrieve a SAML Token, which is then forwarded on to the backend service.

Tuesday, October 14, 2014

Using JAAS with Apache CXF

Apache CXF supports a wide range of tokens for authentication (SAML, UsernameTokens, Kerberos, etc.), and also offers different ways of authenticating these tokens. A standard way of authenticating a received token is to use a JAAS LoginModule. This article will cover some of the different ways you can configure JAAS in CXF, and some of the JAAS LoginModules that are available.

1) Configuring JAAS in Apache CXF

There are a number of different ways to configure your CXF web service to authenticate tokens via JAAS. For all approaches, you must define the System property "java.security.auth.login.config" to point towards your JAAS configuration file.

1.1) JAASLoginInterceptor

CXF provides a interceptor called the JAASLoginInterceptor that can be added either to the "inInterceptor" chain of an endpoint (JAX-WS or JAX-RS) or a CXF bus (so that it applies to all endpoints). The JAASLoginInterceptor typically authenticates a Username/Password credential (such as a WS-Security UsernameToken or HTTP/BA) via JAAS. Note that for WS-Security, you must tell WSS4J not to authenticate the UsernameToken itself, but just to process it and store it for later authentication via the JAASLoginInterceptor. This is done by setting the JAX-WS property "ws-security.validate.token" to "false".

At a minimum it is necessary to set the "contextName" attribute of the JAASLoginInterceptor, which references the JAAS Context Name to use. It is also possible to define how to retrieve roles as part of the authentication process, by default CXF assumes that javax.security.acl.Group Objects are interpreted as "role" Principals. See the CXF wiki for more information on how to configure the JAASLoginInterceptor. After successful authentication, a CXF SecurityContext Object is created with the name and roles of the authenticated principal.

1.2) JAASAuthenticationFeature

Newer versions of CXF also have a CXF Feature called the JAASAuthenticationFeature. This simply wraps the JAASLoginInterceptor with default configuration for Apache Karaf. If you are deploying a CXF endpoint in Karaf, you can just add this Feature to your endpoint or Bus without any additional information, and CXF will authenticate the received credential to whatever Login Modules have been configured for the "karaf" realm in Apache Karaf.

1.3) JAASUsernameTokenValidator

As stated above, it is possible to validate a WS-Security UsernameToken in CXF via the JAASLoginInterceptor or the JAASAuthenticationFeature by first setting the JAX-WS property "ws-security.validate.token" to "false". This tells WSS4J to avoid validating UsernameTokens. However it is possible to also validate UsernameTokens using JAAS directly in WSS4J via the JAASUsernameTokenValidator. You can configure this validator when using WS-SecurityPolicy via the JAX-WS property "ws-security.ut.validator".

2) Using JAAS LoginModules in Apache CXF

Once you have decided how you are going to configure JAAS in Apache CXF, it is time to pick a JAAS LoginModule that is appropriate for your authentication requirements. Here are some examples of LoginModules you can use.

2.1) Validating a Username + Password to LDAP / Active Directory

For validating a Username + Password to an LDAP / Active Directory backend, use one of the following login modules:
  • com.sun.security.auth.module.LdapLoginModule: Example here (context name "sun").
  • org.eclipse.jetty.plus.jaas.spi.LdapLoginModule: Example here (context name "jetty"). Available via the org.eclipse.jetty/jetty-plus dependency. This login module is useful as it's easy to retrieve roles associated with the authenticated user.
2.2) Validating a Kerberos token

Kerberos tokens can be validated via:
  • com.sun.security.auth.module.Krb5LoginModule: Example here.
2.3) Apache Karaf specific LoginModules

Apache Karaf contains some LoginModules that can be used when deploying your application in Karaf:
  • org.apache.karaf.jaas.modules.properties.PropertiesLoginModule: Authenticates Username + Passwords and retrieves roles via "etc/users.properties".
  • org.apache.karaf.jaas.modules.properties.PublickeyLoginModule: Authenticates SSH keys and retrieves roles via "etc/keys.properties".
  • org.apache.karaf.jaas.modules.properties.OsgiConfigLoginModule: Authenticates Username + Passwords and retrieves roles via the OSGi Config Admin service.
  • org.apache.karaf.jaas.modules.properties.LDAPLoginModule: Authenticates Username + Passwords and retrieves roles from an LDAP backend.
  • org.apache.karaf.jaas.modules.properties.JDBCLoginModule:  Authenticates Username + Passwords and retrieves roles from a database.
  • org.apache.karaf.jaas.modules.properties.SyncopeLoginModule: Authenticates Username + Passwords and retrieves roles via the Apache Syncope IdM.
See Jean-Baptiste Onofré's excellent blog for a description of how to set up and test the SyncopeLoginModule. Note that it is also possible to use this LoginModule in other containers, see here for an example.

Thursday, October 9, 2014

New Apache WSS4J releases

Apache WSS4J 1.6.17 and 2.0.2 have been released. WSS4J 2.0.2 picks up some bug fixes via Apache Santuario and BouncyCastle dependency upgrades, in particular the latter upgrade fixes some Kerberos issues. Both releases contain some changes to how SAML tokens are processed that will be described in a forthcoming blog post.

I also added a new Security Advisories page to the WSS4J website. For the moment it just contains some links and information on downstream security advisories that might be relevant to users of WSS4J.

Wednesday, October 8, 2014

Some recent WS-Trust client topics in Apache CXF

There are a number of minor new features and changes in recent versions of Apache CXF with respect to the client side of WS-Trust, which will be documented in this post.

1) STSClient configuration

CXF's STSClient is responsible for communicating with a Security Token Service (STS) via the WS-Trust protocol, in order to issue/validate/renew/etc. a security token. To support WS-Trust on the client side in CXF, it is necessary to construct an STSClient instance, and then reference it via the JAX-WS property key "ws-security.sts.client". Here is a typical example in spring.

However, there are some alternatives to configuring an STSClient per JAX-WS client object (see the CXF documentation for additional information). Strictly speaking these alternatives have been available in previous versions of CXF, however some bugs were fixed in the latest releases to enable them to work properly:

a) If no STSClient is directly configured on the JAX-WS client, then the CXF runtime will look for an STSClient bean with a name that corresponds to the Endpoint name with the suffix ".sts-client". Here is an example:

<bean id="stsClient" class="org.apache.cxf.ws.security.trust.STSClient"
    name="{http://www.example.org/contract/DoubleIt}DoubleItTransportSAML1Port.sts-client"
    abstract="true"
>

b) If no STSClient is configured either directly on the client, or else via the approach given in (a) above, then the security runtime tries to fall back to a "default" client. All that is required here is that the name of the STSClient bean should be "default.sts-client". Here is an example:

<bean id="stsClient" class="org.apache.cxf.ws.security.trust.STSClient"
    name="default.sts-client"
    abstract="true"
>

2) Falling back to Issue after a failed Renew

When a cached SecurityToken is expired, the STSClient tries to renew the token. However, not all STS instances support the renewal binding of WS-Trust. Therefore a new configuration parameter was introduced:
  • SecurityConstants.STS_ISSUE_AFTER_FAILED_RENEW ("ws-security.issue.after.failed.renew") -  Whether to fall back to calling "issue" after failing to renew an expired token. The default is "true".
 3) Renewing security tokens that are "about to" expire

There is a potential issue when a cached security token is "about to" expire. The CXF client will retrieve the cached token + check to see whether the token is expired or not. If it is expired, then it renews the token. If the token is valid, then it uses it in the service request. However, if the security token expires "en route" to the service, then the service will reject the token, and the service invocation will fail.

In CXF 2.7.13 and 3.0.2, support has been added to forcibly renew tokens that are about to expire, rather than risk letting them expire en route. A new configuration parameter has been introduced:
  • SecurityConstants.STS_TOKEN_IMMINENT_EXPIRY_VALUE ("ws-security.sts.token.imminent-expiry-value") - The value in seconds within which a token is considered to be expired by the client, i.e. it is considered to be expired if it will expire in a time less than the value specified by this tag.
The default value for this parameter for CXF 3.0.2 is "10", meaning that if a security token will expire in less than 10 seconds, it will be renewed by the client. For CXF 2.7.13, the default value is "0" for backwards compatibility reasons, meaning that this functionality is disabled.

Tuesday, October 7, 2014

Apache CXF Authentication and Authorization test-cases III

This is the third in a series of posts on authentication and authorization test-cases for web services using Apache CXF. The first post focused on authenticating and authorizing web service requests that included a username and password (WS-Security UsernameToken and HTTP/BA). The second article looked at more sophisticated ways of performing authentication and authorization, such as using X.509 certificates, using a SecurityTokenService (STS), using XACML and using Kerberos. This article will build on the previous articles to show how to perform Single Sign On (SSO) with Apache CXF.

The projects are as follows:
  • cxf-shiro: This project uses Apache Shiro for authenticating and authorizating a UsernameToken, as covered in the first article. However, it also now includes an SSOTest, which shows how to use WS-SecureConversation for SSO. In this scenario an STS is co-located with the endpoint. The client sends the UsernameToken to the STS for authentication using Apache Shiro. The STS returns a token and a secret key to the client. The client then makes the service request including the token and using the secret key to sign a portion of the request, thus proving proof-of-possession. The client can then make repeated invocations without having to re-authenticate the UsernameToken credentials.
  • cxf-sts:  This project shows how to use the CXF SecurityTokenService (STS) for authentication and authorization, as covered in the second article. It now includes an SSOTest to show how to achieve SSO with the STS. It demonstrates how the client caches the token after the initial invocation, and how it can make repeated invocations without having to re-authenticate itself to the STS.
  • cxf-saml-sso: This project shows how to leverage SAML SSO with Apache CXF to achieve SSO for a JAX-RS service. CXF supports the POST + redirect bindings of SAML SSO for JAX-RS endpoints. As part of this demo, a mock CXF-based IdP is provided which authenticates a client using HTTP/BA and issues a SAML token using the CXF STS. Authorization is also demonstrated using roles embedded in the issued SAML token. 
  • cxf-fediz-federation-sso: This project shows how to use the new CXF plugin of Apache Fediz 1.2.0 to authenticate and authorize clients of a JAX-RS service using WS-Federation. This feature will be documented more extensively at a future date, and is considered experimental for now. Please play around with it and provide feedback to the CXF users list.

Thursday, September 25, 2014

Apache Santuario - XML Security for Java 2.0.2 release

Apache Santuario - XML Security for Java 2.0.2 has been released. This is a minor release that fixes a couple of bugs with the streaming code and contains a few dependency upgrades.

Thursday, July 3, 2014

New Apache Santuario releases

Two new versions of the Apache Santuario - XML Security for Java project have been released. Version 2.0.1 (release notes) adds support for a number of previously unsupported algorithms, such as RSA with SHA-224, the RIPE-MD160 digest algorithm, and the RSASSA-PSS signature scheme. It also fixes a performance regression when evaluating signatures, a UTF-8 encoding issue with certain characters, an issue with using GCM algorithms with JDK 8, and a race condition in the streaming decryption code. Version 1.5.7 (release notes) contains the UTF-8, GCM and signature performance fixes, along with a number of other minor changes.

Friday, June 20, 2014

Apache CXF Fediz 1.1.1 released

Apache CXF Fediz 1.1.1 and 1.0.4 have been released. Fediz is a subproject of Apache CXF which implements the WS-Federation Passive Requestor Profile. It allows you to secure web applications using Single Sign-On (SSO) and Claims Based Access Control (CBAC), by redirecting users to an IdP (Identity Provider) for authentication, which in turn leverages the CXF STS (SecurityTokenService). Plugins are provided for the most popular web application containers, such as Apache Tomcat, Jetty, Spring, etc.

The 1.0.4 release  upgrades the underlying CXF dependency from 2.6.6 to 2.6.14, and the 1.1.1 release upgrades CXF from 2.7.7 to 2.7.11, thus picking up important bug fixes. Fediz 1.0.4 adds support for the wauth + whr parameters, while Fediz 1.1.1 adds support for wreq (see section 1.d below) and the older WS-Policy namespace, along with a few other bug fixes. See the Fediz JIRA for more information.

1) Fediz example

In a previous post introducing Apache CXF Fediz I gave instructions about how to deploy one of the Fediz 1.0.x examples to Apache Tomcat. In this section, I will update the deployment instructions for Fediz 1.1.1, as the examples have changed slightly since 1.0.x. In addition, I will give a simple example about how to use the new support for the "wreq" parameter added in Fediz 1.1.1 as part of FEDIZ-84 to request a SAML 1.1 token from the IdP.

Download the latest Apache CXF Fediz release (currently 1.1.1) here, and extract it to a new directory (${fediz.home}). It ships with two examples, 'simpleWebapp' and 'wsclientWebapp'. We will cover the former as part of this tutorial. We will use a Apache Tomcat 7 container to host both the Idp/STS and service application - this is not recommended, but is an easy way to get the example to work. Please see the associated README.txt of the simpleWebapp example for more information about how to deploy the example properly. Most of the deployment information in this section is based on the Fediz Tomcat documentation, which I recommend reading for a more in-depth treatment of deploying Fediz to Tomcat.

a) Deploying the IdP/STS

To deploy the Idp/STS 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
Now we need to set up TLS:
  • Copy ${fediz.home}/examples/samplekeys/idp-ssl-server.jks to ${catalina.home}.
  • Edit the TLS Connector in ${catalina.home}/conf/server.xml', e.g.: <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150" scheme="https" secure="true" keystoreFile="idp-ssl-server.jks" keystorePass="tompass" clientAuth="false" sslProtocol="TLS" URIEncoding="UTF-8"  />
Now start Tomcat, and check that the STS is live by opening the STS WSDL in a web browser: 'https://localhost:8443/fediz-idp-sts/REALMA/STSServiceTransport?wsdl'

b) Deploying the service

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.
c) 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.

Finally, you can see the metadata of the service via the standard URL:
  • https://localhost:8443/fedizhelloworld/FederationMetadata/2007-06/FederationMetadata.xml 
d) Obtaining a SAML 1.1 token via wreq

Let's assume that the Service Provider can only handle SAML 1.1 tokens. Fediz 1.1.1 supports this by allowing the service provider to configure a "request" parameter to send a WS-Trust RequestSecurityToken Element to the IdP containing a desired TokenType. To update the example above to obtain a SAML 1.1 token instead of a SAML 2.0 token do the following:
  • Update ${catalina.home}/conf/fediz_config.xml + add the following to the "protocol" section: <request type="String">&lt;RequestSecurityToken xmlns=&quot;http://docs.oasis-open.org/ws-sx/ws-trust/200512&quot;&gt;&lt;TokenType&gt;http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1&lt;/TokenType&gt;&lt;/RequestSecurityToken&gt;</request>
Now simply follow the same steps as before in accessing 'fedizhelloworld/secure/fedservlet' in a browser. You will see that the Bootstrap token that appears on the final screen is now a SAML 1.1 token.

Thursday, May 29, 2014

Apache CXF Authentication and Authorization test-cases II

In a previous blog post, I covered a number of Apache CXF-based authentication and authorization testcases I uploaded to github. The testcases showed how to authenticate and authorize a SOAP request containing either a SOAP UsernameToken or HTTP Basic Authentication. The options for authentication/authorization backends included Apache DS (ldap), Apache Syncope, Apache Shiro, and Spring Security. In this post, I will cover a number of more advanced authentication and authorization testcases for JAX-WS services using Apache CXF.

The new projects are as follows:
  • cxf-x509: This shows how to use X.509 tokens for authentication and authorization. The service has a TransportBinding policy with an EndorsingSupportingToken X509Token policy. The roles of the authenticated client are mocked by a WSS4J Validator for this demo, but could be retrieved from (e.g) an ldap backend in a real-world demo.
  • cxf-sts: The service in this demo has a TransportBinding policy with an EndorsingSupportingToken IssuedToken policy, requiring a SAML 2.0 token in a client request. The client obtains a SAML token from the CXF SecurityTokenService (STS) and includes it in the service request (also signing the request using the private key which corresponds to the certificate in the SAML token). An Authorization test is also available which uses Claims in the policy to tell the STS to add the roles of the client in the SAML token, which are then used for RBAC on the service side.
  • cxf-sts-xacml: Similar to the cxf-sts demo, this testcase requires a SAML 2.0 token from the STS with the roles of the client embedded in the token. The service is then configured to create a XACML request and dispatch it to a Policy Decision Point (PDP) for authorization. The service endpoint then enforces the authorization decision of the PDP. This demo ships with a mocked PDP implementation. For an enterprise-grade PDP which works with CXF, please see Talend ESB.
  • cxf-kerberos: The service in this demo requires a Kerberos token over TLS. A Kerberos KDC is started as part of the demo, and a CXF JAX-WS client obtains a token and sends it across to the service for authentication. Spnego is also demonstrated as part of this test-case.
These demos build on the first set of demos, which gave different ways to authentication/authorize Username+Password based requests. They show how to authenticate requests using X.509 Tokens, Kerberos tokens and SAML tokens, as well as how to retrieve SAML tokens from an STS, and how to authorize requests using XACML. Please feel free to download + play around with the testcases.

Wednesday, May 21, 2014

Apache CXF 3.0.0 released

Apache CXF 3.0.0 has been released. CXF 3.0.0 picks up Apache Santuario 2.0.0 and WSS4J 2.0.0, and hence all of the new streaming XML/WS-Security functionality available in those releases. Please see the CXF 3.0.0 migration guide for more details about upgrading from an older release. I've also updated the CXF Authentication and Authorization tests in my github repo to use CXF 3.0.0.

Wednesday, May 7, 2014

Apache WSS4J 2.0.0 released

Apache WSS4J 2.0.0 has been released. This major new release features a new StAX-based implementation of WS-Security, as well as a whole host of other changes and features. I've collected a lot of the information on this blog and created a User Guide for WSS4J as a result, so this is a good place to start to learn about the project and the new features of the release.

Tuesday, May 6, 2014

Apache Santuario - XML Security for Java 2.0.0

Apache Santuario - XML Security for Java 2.0.0 has been released, after many months of development work. The main new feature of this release is a new StAX-based API for XML Signature and Encryption. Please see the following page for an overview of this functionality, with some links back to this blog containing configuration and samples. In addition to this new API, the other changes of note in this release are that the JSR-105 API has been removed, and instead will be picked up from the JDK. This simplifies deployment in OSGi containers. In addition, the minimum supported JDK version for this release is now Java 6.

Apache WSS4J 2.0.0 - part VIII

This is the eight and final article on Apache WSS4J 2.0.0. In the previous post, I discussed how to use the new streaming WS-Security functionality of Apache WSS4J 2.0.0 via the "action" based configuration approach. In this post, I will show how the new streaming functionality can be used with Apache CXF when using WS-SecurityPolicy. I will also discuss the limitations of the streaming code compared to the older DOM implementation of WS-Security.

1) Streaming WS-Security functionality via WS-SecurityPolicy

As stated in the previous article, WSS4J must be used with a SOAP stack such as Apache CXF, Axis, etc. to secure messages via WS-Security. Both CXF and Axis support WS-SecurityPolicy, which means that you can use a standard WS-Policy expression to configure the security requirements for your service, and CXF/Axis/etc. will parse the policy and set up WSS4J appropriately. The user only has to configure things like usernames, keystores, etc. Apache CXF 3.0.0 supports using the new streaming functionality of Apache WSS4J 2.0.0, via the new boolean JAX-WS property:
  • SecurityConstants.ENABLE_STREAMING_SECURITY ("ws-security.enable.streaming") - whether to use the new streaming WS-Security implementation with WS-SecurityPolicy, or the older DOM implementation. The default is "false".
So switching to use the new streaming implementation is as simple as setting a boolean configuration property on your CXF client/endpoint.

2) Limitations of the streaming WS-Security implementation in WSS4J 2.0.0

WS-Security (and WS-SecurityPolicy) covers a wide area in terms of requirements and features. The new streaming implementation in WSS4J 2.0.0 meets 90%+ of the most common use-cases. However, some things are not implemented, and the user will have to use the DOM implementation instead for these requirements. The limitations are:
  • XPath evaluation is not supported apart from certain simple expressions. XPath evaluations are used with WS-SecurityPolicy RequiredElements, SignedElements, (Content)EncryptedElements. XPath expressions that point directly to the element are supported, e.g. /soap:Envelope/soap:Header/wsa:To.
  • WS-SecurityPolicy "Strict" Layout validation is not enforced. This includes enforcing whether a Timestamp is first or last.
  • A SymmetricBinding policy with a ProtectTokens assertion is not supported.
  • The combination of EncryptBeforeSigning + EncryptSignature policies are not supported.
  • Deriving keys from Username Tokens (Endorsing Username Tokens) are not supported.
  • Endorsing tokens don't work with Symmetric + Asymmetric binding on the client side, unless the endorsing token is a SAML or IssuedToken.
  • Derived Endorsing Tokens are not supported on the client side.


Thursday, May 1, 2014

Apache WSS4J 2.0.0 - part VII

This is the seventh in a series of articles on Apache WSS4J 2.0.0. Up to now I've discussed the new features and changes for the older DOM implementation of WS-Security in WSS4J 2.0.0. This post will look at using the new streaming WS-Security functionality available in WSS4J 2.0.0, when security is configured via the "action"-based approach (as opposed to using WS-SecurityPolicy).

The WSS4J user guide has an article about the different ways to use WSS4J. The "action" based approach is when you specify a series of security actions to be performed on the outbound side. On the inbound side, the actions are used to verify that the security requirements you were expecting in the message were enforced. Aside from specifying actions, you also need to configure WSS4J with keystore information, usernames, CallbackHandler implementations to retrieve passwords, algorithms to use, etc. See the WSS4J user guide for more information on the configuration options for WSS4J.

1) Streaming WS-Security functionality via the "action" approach

WSS4J must be used with a SOAP stack such as Apache CXF, Axis, etc. to secure messages via WS-Security. For example, Apache CXF has two interceptors WSS4JOutInterceptor and WSS4JInInterceptor that use WSS4J under the hood to apply WS-Security to an outbound + inbound message. Both classes take a Map<String, Object> constructor argument, which is the set of WSS4J configuration options. So how do we switch over to use the new streaming WS-Security implementation in CXF 3.0.0? Easy, simply change the interceptors to WSS4JStaxOutInterceptor and WSS4JStaxInInterceptor! Both of these interceptors also take the same Map<String, Object> as constructor arguments.

2) Configuration differences between the DOM + StAX implementations

The new StAX functionality in WSS4J was designed to be configured in an almost identical way to the DOM code. For the vast majority of use-cases, the configuration will be exactly the same, meaning that you only need to change the interceptor names to pick up the new functionality. Both stacks share the same ConfigurationConstants class. The only substantive difference is that the StAX implementation supports two actions, that the DOM implementation does not:
  • SIGNATURE_WITH_KERBEROS_TOKEN - Perform a Signature action with a kerberos token.
  • ENCRYPT_WITH_KERBEROS_TOKEN - Perform a Encryption action with a kerberos token.
In conclusion, a user of Apache CXF should find migrating to use the new streaming implementation of WSS4J 2.0.0 as simple as changing the interceptor names (with the caveat that WSS4J 2.0.0 requires some configuration changes for both the DOM + StAX implementations, as covered in previous blog entries).

Wednesday, April 30, 2014

New security advisories for Apache CXF

Four new security advisories have been disclosed for Apache CXF. They are:
  • CVE-2014-0109: HTML content posted to SOAP endpoint could cause OOM errors
  • CVE-2014-0110: Large invalid content could cause temporary space to fill
  • CVE-2014-0034: The SecurityTokenService accepts certain invalid SAML Tokens as valid
  • CVE-2014-0035: UsernameTokens are sent in plaintext with a Symmetric EncryptBeforeSigning policy
Please see the security advisories page of Apache CXF for more information. Users are strongly encouraged to upgrade to the latest releases (2.6.14 and 2.7.11).

Tuesday, April 29, 2014

XML Security improvements for JAX-RS in Apache CXF 3.0.0

Recently on this blog, I've covered the new streaming XML Security functionality that will be available in Apache Santuario - XML Security for Java 2.0.0. For more information about why to use the new streaming implementation, as well as how to use it, please review the following - XML Signature is covered here,  XML Encryption is covered here, and some memory benchmarks are presented here. This article will cover using the new streaming XML Security implementation with JAX-RS messages in Apache CXF 3.0.0.

Apache CXF has the ability to secure JAX-RS clients and service XML requests with both XML Signature and Encryption, please see the CXF documentation for more information. Given that a new StAX-based XML Security implementation was available via Apache Santuario - XML Security for Java 2.0.0, it was natural to port this to CXF to be used by JAX-RS clients and endpoints. To show how to use the new functionality (as well as the older DOM-based XML Security functionality), I've created a new cxf-jaxrs-xmlsecurity project in github.

1) XML Signature test-cases

The following tests show how to use XML Signature with JAX-RS clients and endpoints:
The clients are configured in code, and the service endpoints are configured in spring. The service configuration for the streaming case is here
 
2) XML Encryption test-cases

The following tests show how to use XML Encryption with JAX-RS clients and endpoints:
The clients are configured in code, and the service endpoints are configured in spring. The service configuration for the streaming case is here

3) Configuration

The streaming XML Security implementation is configured in a very similar way to the DOM implementation. In the tests above, the same configuration parameters (usernames, keys, callbackhandler, etc.) are passed as properties for both implementations. One difference is that the streaming implementation has a single unified interceptor for both XML Signature and XML Encryption, whereas the DOM code has separate interceptors for both cases.

For the outbound case, the interceptor is XmlSecOutInterceptor. This interceptor
has the following properties that can be configured:
  • EncryptionProperties encryptionProperties - An EncryptionProperties Object to use to configure algorithms for encryption.
  • SignatureProperties sigProps - A SignatureProperties Object to use to configure algorithms for signature.
  • boolean encryptSymmetricKey - Whether to encrypt the symmetric key or not in an EncryptedKey. The default is true.
  • SecretKey symmetricKey - A symmetric key to use. If not specified, it is generated randomly.
  • boolean signRequest - Whether to sign the request or not. Default is false.
  • boolean encryptRequest - Whether to encrypt the request or not. Default is false.
  • List<QName> elementsToSign - The QNames of Elements in request to sign. If not specified the entire request is signed.
  • List<QName> elementsToEncrypt - The QNames of Elements in request to encrypt. If not specified the entire request is encrypted.
  • boolean keyInfoMustBeAvailable - Whether to add a KeyInfo structure or not to the signature/encryption. The default is true.
The inbound interceptor is XmlSecInInterceptor. This has the following properties that can be configured:
  • EncryptionProperties encryptionProperties - An EncryptionProperties Object to use to configure algorithms for encryption.
  • SignatureProperties sigProps - A SignatureProperties Object to use to configure algorithms for signature. 
  • String decryptionAlias - The alias to use to retrieve a private key from the keystore to decrypt the request. If not specified it falls back to the default alias in the Crypto properties file (if specified).
  • String signatureVerificationAlias - The alias to use to retrieve a certificate/public key from the keystore to verify the Signature, if the Signature does not contain a KeyInfo with a complete certificate/key.
  • boolean requireSignature - Whether the request must be signed. The default is false.
  • boolean requireEncryption - Whether the request must be encrypted. The default is false.
4) Some observations

The new streaming JAX-RS XML Security implementation is quite similar in terms of functionality and behaviour to the older DOM implementation. However there are a few differences to note:
  • The DOM-based XML Signature implementation supports Enveloped, Enveloping and Detached "styles". The StAX implementation only supports Enveloped.
  • The decryption alias must be supplied for the StAX case (or a default alias in the Crypto properties file). The DOM code takes the EncryptedKey and checks for a matching private key in the Crypto properties file. The StAX code expects to be supplied with the matching private key.
  • The XmlSecInInterceptor has booleans "requireSignature" and "requireEncryption" which should be set if you want to enforce that a message should be signed and/or encrypted. However, there are some scenarios where the internal interceptor that enforces these requirements may run before security processing has finished. If you are seeing exceptions along these lines, then disable the boolean values, but it is up to you then to retrieve the stored security values and match them against the security requirements.

Friday, April 25, 2014

Apache Santuario - XML Security for Java 2.0.0 - part III

In the previous couple of posts, I've introduced the new streaming functionality of Apache Santuario - XML Security for Java 2.0.0. The first post focused on XML Signature and the second post focused on XML Encryption. This post will discuss the performance of the new streaming approach. In particular, we will focus on the memory consumption of the DOM vs StAX implementations as the size of the XML tree increases. Both implementations are roughly equivalent in terms of timing, however as we will see there is a big different in terms of memory usage.

1) Encryption

Here is a graph that shows the memory consumption of the StAX versus DOM implementations for encryption, as the size of the XML tree grows.



2) Decryption

Here is a graph that shows the memory consumption of the StAX versus DOM implementations for decryption, as the size of the XML tree grows.


3) Signature Creation

Here is a graph that shows the memory consumption of the StAX versus DOM implementations for signature creation, as the size of the XML tree grows. This is the only case where the memory consumption of the streaming code does not remain relatively flat, as some caching is involved in the signature creation case. However, the memory consumption is still substantially less than for the DOM code.


4) Signature Verification

Here is a graph that shows the memory consumption of the StAX versus DOM implementations for signature verification, as the size of the XML tree grows.


5) Conclusion

The new streaming implementation in Apache Santuario - XML Security for Java uses far less memory for large XML trees than the current DOM implementation for XML Encryption and XML Signature verification. It also uses substantially less memory for large XML trees for XML Signature creation. If you are working with large XML trees then you should experiment with the new functionality to see if it improves performance.

Wednesday, April 23, 2014

Apache Santuario - XML Security for Java 2.0.0 - part II

In the previous blog post, I covered the new StAX-based (streaming) XML Signature functionality coming in Apache Santuario - XML Security for Java 2.0.0. In this post, I will focus on the new streaming XML Encryption functionality that will also be available in this release.

1) XML Encryption test-cases

I have uploaded some test-cases to github to show how to use the new StAX-based API. The tests and setup mirror the XML Signature testcases that I covered in the previous blog post. There are currently three junit tests in this project:

2) Outbound StAX configuration

To see how to configure the new outbound StAX-based XML Encryption functionality, take a look at the "encryptUsingStax" method used by the tests. The streaming XML Security functionality is configured by populating a XMLSecurityProperties Object. You must typically call the following methods for XML Encryption:
  • properties.setAction(XMLSecurityConstants.Action) - an "Action" to perform, which for XML Encryption purposes is XMLSecurityConstants.ENCRYPT. 
  • properties.setEncryptionKey(Key) - The encrypting key. Typically a SecretKey instance.
  • properties.setEncryptionSymAlgorithm(String) - Symmetric encryption Algorithm to use. The default is AES 256.
  • properties.addEncryptionPart(SecurePart) - Add a SecurePart to encrypt, e.g. encrypt a given QName. 
  • properties.setEncryptionTransportKey(Key) - The key to use to encrypt the secret key (if desired). Either a SecretKey or PublicKey instance.
  • properties.setEncryptionKeyTransportAlgorithm(String) - The encryption key transport algorithm to use, to encrypt the secret key (if desired). Default is RSA OAEP.
  • properties.setEncryptionKeyIdentifier(SecurityTokenConstants.KeyIdentifier) - How to reference the encrypting key/cert. The default is SecurityTokenConstants.KeyIdentifier_IssuerSerial.  
The valid Encryption KeyIdentifier types are:
  • SecurityTokenConstants.KeyIdentifier_KeyValue
  • SecurityTokenConstants.KeyIdentifier_KeyName
  • SecurityTokenConstants.KeyIdentifier_IssuerSerial
  • SecurityTokenConstants.KeyIdentifier_SkiKeyIdentifier
  • SecurityTokenConstants.KeyIdentifier_X509KeyIdentifier
  • SecurityTokenConstants.KeyIdentifier_X509SubjectName
  • SecurityTokenConstants.KeyIdentifier_NoKeyInfo
3) Inbound StAX configuration

To see how to configure the new inbound StAX-based XML Encryption functionality, take a look at the "decryptUsingStAX" method used by the tests. As with encryption creation, it is necessary to create a XMLSecurityProperties Object, and to tell it what "Action" to perform. In addition you must call the following method:
  • properties.setDecryptionKey(Key) - a key to use to decrypt the request.
In addition, it is possible to pass a SecurityEventListener to record what security events were performed (see TestSecurityEventListener used in the tests). This allows the user to check what algorithms were used, what was encrypted etc.