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.