Monday, April 9, 2012

Part 2 - x509 Authentication with Spring, Eclipse, Jetty and Maven

Introduction

I've seen a few posts to Stack Overflow recently regarding x509 authentication using Spring. I know from my own experience that finding a single tutorial that has everything in one place is difficult, so I'd thought I would put one together that covers pretty much everything you need to get a simple web application going

I'm going to break this up into 4 parts:
  • Part 1 : Generation of a client & server self-signed certificates (with common self-signed CA root certificate)
  • Part 2 : Maven web application archetype generation and maven-jetty-plugin configuration
  • Part 3 : Using a simple in-memory authorization provider
  • Part 4 : Web application debugging using Eclipse

Part 2 - Maven web application

I am going to present the generation of a simple Java web application using a Maven archetype, and configuration of the maven-jetty-plugin to allow local testing

Maven archetype generation

I'm using a Maven archetype to build a template for my web application project, which can be easily accomplished with the following command: After which you'll have a Maven managed Java project, with templated folders and files for a simple web application:
./whitey-webapp
./whitey-webapp/src
./whitey-webapp/src/main
./whitey-webapp/src/main/resources
./whitey-webapp/src/main/webapp
./whitey-webapp/src/main/webapp/WEB-INF
./whitey-webapp/src/main/webapp/WEB-INF/web.xml
./whitey-webapp/src/main/webapp/index.jsp
./whitey-webapp/pom.xml

Maven-jetty-plugin configuration

We now want to configure the maven-jetty-plugin, which will allow us to bring up a jetty web container instance and host our web application.

Open up the pom.xml and add the following plugin definition into your project->build->plugins section: You'll notice we're referencing the server certificate and trust store created in part 1 - be sure to copy them into the src/test/certs folder before continuing (you'll need to create the directory). You should now be able to use Maven to run the jetty:run goal and test your jetty configuration: Note: If you get an error about the org.maven.plugins:maven-jetty-plugin not existing then you'll need to add a section to your ~/.m2/settings.xml file:

Browser validation

So now you've got the jetty server up and running, open up your browser and go to https://localhost:8443/whitey-webapp, you should get an error to the effect of ssl_error_bad_cert_alert (Firefox). This is for a number of reasons:
  • Your browser doesn't trust the server, and doesn't have a client certificate compatible for the server's trust store
  • The server requires a client certificate (that's the needClientAuth=true portion of the maven-jetty-plugin configuration)
To enable us to successfully connect to the server, you'll now need to configure your browser. Without going into details for each and every browser out there you need to complete two things:
  1. Import the CA root certificate (ca.crt) generated in part 1 into your browsers list of trusted Authorities
  2. Import the client certificate (client.p12) generated in part 1 into your browsers list of user certificates
With this complete, point your browser at https://localhost:8443/whitey-webapp. You'll most probably get a warning message - because the server certificate's common name (Test Server) doesn't match the name of the server (localhost). You should be able to convince your browser to ignore this message and continue.

With any luck, you should see a Hello World web page, which has been delivered over SSL

4 comments:

  1. This is a great series of posts! It's been extremely helpful for me, particularly the tidbits about configuring your browser for client authentication.

    One extra piece of information in that regard, for anyone who happens to stumble on this. If you're using Firefox and you have imported client certificates, when you are prompted to select a client certificate to send to the server as identification, you will only be able to choose certificates that have a CA which is in the server's truststore.

    This shouldn't be an issue for anyone using legit, commercial certificates, but if you've gone the fully self-signed route, make sure you've imported your CA cert into your server's truststore.

    ReplyDelete
  2. Thanks for these posts! They've been extremely helpful. You mentioned... "With any luck, you should see a Hello World web page, which has been delivered over SSL". Do you have a zip file of this sample project available?

    ReplyDelete
  3. I'm not sure i have the source anymore, but i can re-create and publish to github - i'll post a link soon

    ReplyDelete