So what I needed to accomplish:
- send automated emails from a webapp using Spring 3.0
- running on a Glassfish / WASÂ instance
- to an SSL/TLS secured SMTP (smtps) service running on a different host
Import the certificate
First of all, we need our jvm to trust the certificate of the remote host that offers the smtps service which in my case is available on port 465 (which is common).
To do that, first of all read Andreas Sterbenz’ old Sun blog post regarding the InstallCert tool he wrote.
Download InstallCert.java to some directory, move to that dir, and run
javac InstallCert.java
Next, run
java InstallCert
from the same dir to get usage instructions.
I went for the version
java InstallCert your.host.com:your_port
After selecting the certificate you want to add to the trusted keystore by pressing the associated number you’ll end up with a file called jssecacerts in your working directory.
Also note the last line of the generated output, which should be something along the lines of:
Added certificate to keystore ‘jssecacerts’ using alias ‘your.host.com-1′
You’ll need that alias for the next step.
Export the certificate from the keystore file ‘jssecacerts’
To do this we’ll use keytool, note the alias name which needs to be equal to the one mentioned in the last step:
keytool -export -alias your.host.com-1 -keystore jssecacerts -file my_actual_cert.cer -storepass changeit
We now have a file representing the actual certificate we need to trust in order for our application to be able to set up a secured connection with your.host.com
Importing the certificate
Before we get to use keytool again, make sure you have proper permissions to modify your JRE installation and go to
<jre_root>/lib/security
Eg. for the Sun (Oracle) JDK on Debian/Ubuntu <JRE_ROOT> could be
/usr/lib/jvm/java-6-sun/jre
You should see a file cacerts in this directory. Next run:
keytool -import -alias your.host.com-1 -file my_actual_cert.cer -keystore cacerts -storepass changeit
This will effectively add the certificate you just exported to the trusted certificates.
Making Glassfish trust our certificates
To do this, you need to point to the trustStore you just updated (cacerts) in the properties associated to the Glassfish JVM.
First of all copy the cacerts keystore file you just updated to <your_glassfish_domain>/config/my-cacerts.jks
Next login to the Glassfish Admin Console, and proceed to
Common Tasks -> Configuration -> JVM Settings -> JVM Options
Change the property
-Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/config/cacerts.jks
to
-Djavax.net.ssl.trustStore=${com.sun.aas.instanceRoot}/config/my-cacerts.jks
Save your changes and restart glassfish.
Making WebSphere Application Server trust our certificate
is documented here (among other places no doubt); basically the same steps.
Sending mail
Check out one of many samples available online showing how to send email using Spring facilities. This is a quick and dirty example without injection.
<bean id="mailSender" p:port="your_port" p:host="your.host.com" p:username="your_authenticating_user" p:password="your_pwd" p:protocol="smtps">
<property name="javaMailProperties">
<props>
<prop key="mail.smtps.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
Afterwards you can just inject the mailSender and use it as desired.
Note that you can easily inject a JNDI mail session, which I didn’t do because there’s no real advantage to warrant having to ensure the proper JNDI resource(s) exist on different servers in this case.
Happy sending!