How to setup SSL on Apache

Setting up SSL on your Apache server is a pretty good idea even if you are only just hosting your own website with a CMS like drupal. With SSL enabled, you can now securely login, make updates, and post blog entries like me :-). Here is what you have to do:

Step 1. Generate an SSL certificate. All you really need is a self signed certificate unless of course you are doing something for work. The command below should do the trick. Just fill out the fields that it prompts you for.
apache2-ssl-certificate

Step 2. Enable the SSL module. The following command should do it:
a2enmod ssl

Step 3. Configure SSL in your virtual host. You will need to add these two lines to your virtual host configuration.
SSLEngine on
SSLCertificateFile /path/to/your.pem

Here is an example of what a virtual host configuration using SSL:
NameVirtualHost *:443
NameVirtualHost *:80
<VirtualHost *:80>
        ServerName your.domain.com
        DocumentRoot /var/www/
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
</VirtualHost>
<VirtualHost *:443>
        ServerName your.domain.com
        DocumentRoot /var/www/
        ErrorLog /var/log/apache2/error.log
        CustomLog /var/log/apache2/access.log combined
        SSLEngine on
        SSLCertificateFile /path/to/your.pem
</VirtualHost>

Chaining SSH Tunnels

So in an early post I described how to create an SSH tunnel. That is fine if you only need to connect to a server by going through a single bastion. In this post, I am going to provide an example for how to connect by going through multiple servers; in other words, how to chain SSH tunnels.

Suppose you want to connect to server E but in order to do so, you have to be on server D that you can only access from C which in turn can only be accessed from B that only A can access. The following should setup the necessary chain of SSH tunnels.

ssh -NL 6000:B:22 -o TCPKeepAlive=no -o ServerAliveInterval=15 A &
ssh -NL 6001:C:22 -o TCPKeepAlive=no -o ServerAliveInterval=15 localhost -p 6000 &
ssh -NL 6002:D:22 -o TCPKeepAlive=no -o ServerAliveInterval=15 localhost -p 6001 &
ssh -NL 6003:E:22 -o TCPKeepAlive=no -o ServerAliveInterval=15 localhost -p 6002 &
ssh localhost -p 6003
Welcome to E!

Adding authentication to an Apache CXF Web Service Client

In my last post, I provided steps for creating an Apache CXF Web Service Client. Now that client only works with Web Services that do not require you to authenticate. In this post, I will provide an example of how add authentication.

Step 1. Create a CXF Web Service client

Step 2. Create a CallbackHandler. The code below is actually from a previous post pertaining to authenticating an Axis 1.4 Web Service Client:

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSPasswordCallback;
public class SamplePWCallback implements CallbackHandler {
   private Configuration _config;
   private static Log _logger = LogFactory.getLog(SamplePWCallback.class);
   public SamplePWCallback () {
      super();
      _logger.info("Initializing Sample PW Callback");
      _config = null;
      try {
         _config = new PropertiesConfiguration("sample.properties");
      }
      catch (ConfigurationException ce) {
         _logger.error("Error loading configuration file", ce);
      }
   }
   public void handle(Callback[] callbacks) throws IOException,
      UnsupportedCallbackException {
      for (int i = 0; i < callbacks.length; i++) {
         if (callbacks[i] instanceof WSPasswordCallback) {
            WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
            // set the password given a username
            if (_config.getString("username").equals(pc.getIdentifier())) {
               pc.setPassword(_config.getString("password"));
            }
         } 
         else {
            throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
         }
      }
   }
}

Step 3. Update your client to use your CallbackHandler. For the purposes of demonstration, let’s assume the global weather Web Service that I used in the previous blog post required authentication. The client would have to be updated to look similar to the sample one below:

import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import net.webservicex.*;
import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor;
import org.apache.cxf.endpoint.Client; 
import org.apache.cxf.endpoint.Endpoint;                      
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; 
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.WSConstants;
public class HelloCXF {
   public static void main (String args[]) {
      try {
         GlobalWeather service = new GlobalWeather(new URL("file:globalweather.wsdl"));
         GlobalWeatherSoap weatherSoap = service.getGlobalWeatherSoap();
         Client client = ClientProxy.getClient( weatherSoap );
         Endpoint endPoint = client.getEndpoint();   
         Map<String, Object> outProperties = new HashMap<String, Object>();
         outProperties.put( WSHandlerConstants.ACTION,
               WSHandlerConstants.USERNAME_TOKEN );
         outProperties.put( WSHandlerConstants.USER, _config.getString("username"));
         outProperties.put( WSHandlerConstants.PASSWORD_TYPE, WSConstants.PW_TEXT );
         outProperties.put( WSHandlerConstants.PW_CALLBACK_CLASS,
               SamplePWCallback.class.getName() );
         WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor( outProperties );
         endPoint.getOutInterceptors().add( wssOut );
         endPoint.getOutInterceptors().add( new SAAJOutInterceptor() );
         endPoint.getInInterceptors().add( new LoggingInInterceptor() );
         endPoint.getOutInterceptors().add( new LoggingOutInterceptor() );

         System.out.println("Weather for New York");
         System.out.println(weatherSoap.getWeather("New York", "United States"));
      }
      catch (MalformedURLException mue) {
         System.err.println("problem with the wsdl url");
         System.exit(1);
      }
   }
}

Axis 1.4 Web Service Client Side authentication

So in a previous post, I gave an example of how to setup an Axis 1.4 Web Service client. That is fine if you do not have to login to use the service. Often times however, you do have to authenticate your client especially if your work has paid for the third party Web Service that you want to use. Here you want to use WSS4J. Below are the steps to get yourself setup:

Step 1. Download WSS4J

Step 2. Add the contents of the WSS4J lib directory to your classpath. If you are working with a project in Eclipse, you probably want to copy the contents of WSS4J lib to your own lib directory

Step 3. Create a deployment descriptor file. Below is an example of one that we will refer to as sample.wsdd:

<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
  <globalConfiguration >
   <requestFlow >
    <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
     <parameter name="action" value="UsernameToken"/>
     <parameter name="user" value="sampleUsername"/>
     <parameter name="passwordCallbackClass" value="SamplePWCallback"/>
     <parameter name="passwordType" value="PasswordDigest"/>
    </handler>
   </requestFlow >
  </globalConfiguration >
</deployment>

Step 4. Create a CallbackHandler. In my example below, I use the Apache configuration package to get the username and password from a properties file in order to avoid hardcoding it.

import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSPasswordCallback;
public class SamplePWCallback implements CallbackHandler {
   private Configuration _config;
   private static Log _logger = LogFactory.getLog(SamplePWCallback.class);
   public SamplePWCallback () {
      super();
      _logger.info("Initializing Sample PW Callback");
      _config = null;
      try {
         _config = new PropertiesConfiguration("sample.properties");
      }
      catch (ConfigurationException ce) {
         _logger.error("Error loading configuration file", ce);
      }
   }
   public void handle(Callback[] callbacks) throws IOException,
      UnsupportedCallbackException {
      for (int i = 0; i < callbacks.length; i++) {
         if (callbacks[i] instanceof WSPasswordCallback) {
            WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];
            // set the password given a username
            if (_config.getString("username").equals(pc.getIdentifier())) {
               pc.setPassword(_config.getString("password"));
            }
         } 
         else {
            throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
         }
      }
   }
}

Step 5. Access your wsdd in your Web Service client. Let’s assume the global weather Web Service that I used in the previous Axis 1.4 blog post required authentication. Here is what your client would look like.

import NET.webserviceX.www.*;
import org.apache.axis.configuration.FileProvider;
public class HelloWeather {
   public static void main(String[] args) throws Exception {
      FileProvider wsdd = new FileProvider("sample.wsdd");
      wsdd.setSearchClasspath(true);
      GlobalWeatherLocator locator = new GlobalWeatherLocator(wsdd);
      GlobalWeatherSoap globalWeatherSoap = locator.getGlobalWeatherSoap();
      System.out.println("Weather for New York");
      System.out.println(globalWeatherSoap.getWeather("New York", "United States"));
   }
}

Logging uncaught exceptions in a Java application

Logging exceptions is pretty important as it allows you to troubleshoot problems that come up with your production applications. If you have a regular Java application, there is a trick to logging uncaught exceptions. Those are the exceptions that do not require you to put your code in a try/catch block. To log these exceptions, you need to set a default uncaught exception handler. The example below defines one that uses log4j to write an ERROR log entry.

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class HelloWorld {
   private static Log _logger = LogFactory.getLog(HelloWorld.class);
   public static void main (String args[]) {
      //setting uncaught exception logging
      Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
         public void uncaughtException(Thread t, Throwable e) {
            _logger.error("An uncaught exception has been thrown", e);          }
      });
   }
}

Using the Spring Expression Language with static properties

One of the things that I love about Spring 3 is the Spring Expression Language (SPEL). At first glance, SPEL does not appear to give you that much; with it, you can execute Java expressions in your Spring config files. This capability, however, is awesome when have properties that take values defined by static variables. For example, how days of the week are defined in the Calendar class:

Calendar.MONDAY
Calendar.TUESDAY
Calendar.WEDNESDAY
Calendar.THURSDAY
Calendar.FRIDAY
Calendar.SATURDAY
Calendar.SUNDAY

Prior to SPEL, if you wanted to set an integer property to Calendar.MONDAY, you had to know and specify the actual integer value for it. Using SPEL, can simply use the following snippet instead; you need to add the org.springframework.expression-3.X.X.jar to your classpath as well.

<property name="dayOfWeek" value="<entry key="#{T(java.util.Calendar).MONDAY}" />

The PhD is done!

Well, that title is slightly deceiving. I am almost done. I successfully defended my thesis earlier this month and pasted in my revisions. I am just waiting to get my committee’s approval before I can official declare that I am done. So yes, that means I can be referred to as Dr. Chris. I am not too sure about using the prefix but I am definitely glad to be done.

Any interesting aside; so I have been doing a lot of Spring development. I have now seen applications that use JSP pages and applications that use Apache Velocity templates. From what I can see, you can actually configure a Spring Web app to use pages that are external to the actual WAR file. There isn’t a whole lot of difference between Velocity and JSP really expect that if condition statements are a little more cumbersome in JSP since you have to use choose, when, otherwise statements and I haven’t really found a good editor for Velocity. In truth, I have to say that I prefer Velocity templates over JSPs though it is because Velocity really forces you to keep your business logic to your Java code as oppose to in your HTML. You can use JSP in the say way but there is nothing stopping you from dumping a whole ton of Java code in there.

I know I have been kind of spotty with my blogging. I’m new at it and have been busy getting wrapping up school and getting settled (excuses I know). I’m going to starting up a new side project with Dr. Toms at Dalhousie so I should have some interesting coding tid bits to post and maybe some user search behavior results.

New City, New Framework

Hey all,

I have just relocated to New York with my wife. I got what looks to be a cool job here and she will be continuing on with her school. It’s been a busy month with moving and settling in but we are getting there.

In my down town, I have started getting back into my usual hackery. I have been reading Craig Walls’ book “Spring in Action”. It is a pretty good book actually. Some people on Amazon have criticized it for a lack of code examples but really, it is a good solid book that explains how Spring works and how to use it properly. If you understand Java, then you don’t really need coding examples, just an explanation of how Spring works.

I am new to the Spring framework though it has been around for many years. It is an interesting framework that helps you build Java systems designed around dependency injection, as known as inversion of control. Essentially, it promotes the development of loosely coupled object which in turn makes them very modular. It also promotes aspect orient programming which allows for modularization of things like logging and security; stuff that is a pain in the butt to do and susceptible to bugs. I am looking forward to using at my new job and making a couple new research search system for my old lab at Dal; logging user behavior was always a pain to do so it should be interesting to see if I can make good use of Spring there.

I am sort of behind of my Web posts due to moving and what not. I actually got a few papers accepted for publication which is a new and happy change from my usual rejections. I will post up the references shortly.

Site official moved over to Drupal

Ok, I have finally moved over all the content from my old Plone site to Drupal. I have to say that Drupal is a little different from Plone in terms of managing a Website. I think that the Plone approach to creating and editing pages and workflows is more intuitive than Drupal. Drupal however is much faster, uses less resources, and far easier to skin. Overall, I am happy with the move to Drupal. The Drupal blog and forum modules are nice too.

Good Bye Plone, Hello Drupal

Hey all,

PhD is all but done now so I decided to rebuild my Website. It needed something new and I was getting tired of Plone. Anyhow, I am moving everything over to the new site in the next few days.

And yes… I have a blog now.