Client Certificate Authentication with JBoss AS 4.2.3

I was currently trying to integrate foaf-ssl single-sign-on, which is a decentralized service to authenticate users with client certificates in Social Semantic Web applications, in KiWi. The idea behind foaf-ssl is that a user has its certificates inside of his browser and is asked to choose one certificate to authenticate with the application. The certificate contains a link to the WebID, which can be used to locate the users` foaf-file, where personal information like first and last name, birthday and eMail address can be found. In my opinion, this is a great opportunity to build applications that are able to import data about identities without annoying them with recurring registration processes and weak password protections.

To use foaf-ssl within your application you may like to build your own identity provider (idp) servlet, which checks the client certificates, extracts the web id from the certificate and redirects to a URL, which has been passed as a GET parameter to the servlet. The first step towards enabling such a service is the configuration of your application server. Henry Story provided a detailed description on how to configure Tomcat 6 to allow client certificate authentication. As JBoss AS 4.2.3 uses Tomcat 6 aswell internally, the configuration of JBoss AS does only slightly differ from the Tomcat 6 configuration.

First of all we’ll have a look into the server.xml file, where the application server connector configurations can be found. You’ll find that file in the ${JBoss.home}/server/default/deploy/jboss-web.deployer directory. The jboss-web.deployer is the Tomcat 6 bundle that JBoss AS integrate. Inside of the server.xml you’ll find a Connector that defines the SSL connections. If you haven’t changed the default configuration yet, the paragraph should be commented out. So the first step for you is to uncomment it and configure it in the following way:

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true" maxThreads="150"
       scheme="https" secure="false" strategy="ms" address="${jboss.bind.address}"
       keystoreFile="${jboss.server.home.dir}/conf/server.keystore"
       keystorePass="changeit" sslProtocol="TLS"
       truststoreFile="/usr/lib/jvm/java-6-sun-1.6.0.10/jre/lib/security/cacerts"
       truststorePass="changeit"
       SSLImplementation="org.jsslutils.extra.apachetomcat6.JSSLutilsImplementation"
       acceptAnyCert="true" clientAuth="want" />

The default https port is 443, but ports below 1024 require that the server is started with root privileges, so we take the default port 8443 for testing purposes instead. As we do not only want to allow server-side authentication, but mutual authentication clientAuth must be at least set to “want”. There are three values for clientAuth: Set it to true if you want the SSL stack to require a valid certificate chain from the client before accepting a connection. Set to want if you want the SSL stack to request a client Certificate, but not fail if one isn’t presented. A false value (which is the default) will not require a certificate chain unless the client requests a resource protected by a security constraint that uses CLIENT-CERT authentication.

As Henry already pointed out in his HowTo descriptions, servers authentify themselves by sending the client a certificate signed by a well known Certificate Authority (CA) whose public key is shipped in all browsers. Browsers use the public key to verify the signature sent by the server. If the server sends a certificate that is not signed by one of these CAs (perhaps it is self signed) then the web browser will usually display some pretty ugly error message, warning the user to stay clear of that site, with some complex way of bypassing the warning, which if the user is courageous and knowledgeable enough will allow him to add the certificate to a list of trusted certs. This warning will put most people off. It is best therefore to buy a CA certified cert.(Henry found one for €15 at trustico.) Usually the CA’s will have very detailed instructions for installing the cert for a wide range of servers. Anyway, for testing purposes it is fair enough to use self-signed certificates.

To enable https connections and persist server, as well as client certificates, it is important to specify the directory of the keystore and the truststore, which will be build in the following. The JVM comes together with a truststore, so you don’t have to create another one. However, you have to specify the directory of the JVM truststore. At least it didn’t work for me to pass on it.

The next step to complete is to build the keystore in the ${JBoss.home}/server/default/conf directory. This can be done with the help of the keytool program, which can be found in the ${JAVA.HOME}/bin directory. To create a keystore, export its certificate and import it into the JVM truststore, type the following command into the console:

.../server/default/conf$ keytool -genkey -alias server -keyalg RSA -keystore server.keystore
.../server/default/conf$ keytool -export -alias server -keystore server.keystore -file server.cer
.../server/default/conf$ keytool -import -v -trustcacerts -alias server -file server.cer -keystore
${JAVA_HOME}/jre/lib/security/cacerts.jks -keypass changeit -storepass changeit

After the first command you'll be asked to fill out some information, for example the keystore password, the first name and last name, the organisation, the city, state, etc.. Note that you should write the host address (www.host.de, 127.0.0.1, etc.) instead of your first and last name for the server keystore, because otherwise the browser complains that the address produced in the keystore is not matching the address that a user typed into the browser.

Another important configuration of server.xml is the link to the custom SSLImplementation (SSLImplementation="org.jsslutils.extra.apachetomcat6.JSSLutilsImplementation"). This library has been provided by Bruno Harbulot and enables to accept any client certificates (when acceptAnyCert is set to true), not just those where the issuer has been trusted before.

Henry explains that necessity in the following paragraph:

Usually servers send in the request to the client a list of Distinguished Names of certificates authorities (CA) they trust, so that the client can filter from the certificates available in the browser those that match. Getting client certificates signed by CA's is a complex and expensive procedure, which in part explains why requesting client certificates is very rarely used: very few people have certificates signed by well known CAs. Instead those services that rely on client certificate tend to sign those certificates themselves, becoming their own CA. This means that certificates end up being valid for only one domain. foaf+ssl bypasses this problem by accepting certificates signed by any CA, going so far as to allow even self signed certs. The server must therefore send an empty list of CAs meaning that the browser can send any certificate (TLS 1.1).

For this to work, the jsslutils library and the jsslutils-extra-apachetomcat6 library must be placed into the ${JBoss.home}/server/default/lib directory.

Having completed these steps should enable your JBoss application server to allow secured https connections which can use any kind of client certificates from the users` browser to authenticate them.

About these ads

About stexx

Junior Researcher and Software Developer at Salzburg Research; just graduated from the University of Applied Sciences in Salzburg and now studies at the University of Salzburg in the faculty of Applied Informatics; loves industrial music and progressive rock (Nine Inch Nails, Tool, A Perfect Circle, Cocoon, etc) and is mostly harmless.
This entry was posted in Application Server, Java Enterprise Edition, Software Development and tagged , , , , . Bookmark the permalink.

One Response to Client Certificate Authentication with JBoss AS 4.2.3

  1. Useful topic. congrats

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s