Showing posts with label Tomcat. Show all posts
Showing posts with label Tomcat. Show all posts

Sunday, June 27, 2010

SSL Configuration in Tomcat

Today, we are going to learn about how to setup SSL on your Tomcat so that you can access your application on HTTPS instead of HTTP and provide a secure interface to your clients. But before going into that, lets understand the basic difference between HTTP & HTTPS.

Introduction to HTTPS

HTTPS (HyperText Transfer Protocol Secure) combines HTTP protocol with SSL (Secure Sockets Layer) or TLS (Transport Layer Security) and offers a secure channel to browse the web so that you can trust the connection to send sensitive information like payment transactions details or your bank account details. The difference between the two clearly shows in the address bar where you can see “https://” instead of “http://”. Also HTTPS uses port 443 as the default port, whereas HTTP uses port 80 as the default port for communication.

Using HTTPS, the two-way communication that occurs between your web browser and the host server is now secure and encrypted. This means that the data being sent is encrypted by one side, transmitted, then decrypted by the other side before processing.

When a web browser initially attempts to contact a web server over a secure connection, it is presented with a “certificate” (set of credentials), as a proof of the site is who what it claims to be. These certificates are signed (digitally verified) by certain authorities like VeriSign and typically purchased by the web server. Remember that you need to buy a certificate for each port on which you want a secure connection. For this blog entry, we will sign our own certificate and make other changes to Tomcat configuration so that it starts accepting connection on port 443 using HTTPS protocol.

But before we begin setting up SSL on Tomcat, its very important to iterate that this is valid only if you are using Tomcat as a stand-alone web server, the other possibility being Microsoft IIS or Apache Server serving as the main interface to the outside world and Tomcat is serving as the JSP/Servlet Container at the backend, communicating with one of these servers. In that case, you have to make SSL configuration changes in IIS or Apache, while Tomcat will continue to work normally sending cleartext responses (no encryption at Tomcat level).

Creating a Certificate

Fortunately, Java provides us with a utility (keytool) which can be used to create a self-signed certificate. This is not validated by any authority, hence not suitable for production use. But it can certainly be used for development purposes. So, lets  create a certificate from scratch for our application:

Type in the following command and enter details(credentials) about your organization that users of your site/application would see in the certificate given to them when they use it. The default password for Tomcat is “changeit” (all in lower-case). It would be asked when you type the following command to generate your self signed certificate:

>> keytool –genkey –alias –tomcat –keyalg RSA

Note, you must enter the password (as told above) and then all the credentials as shown below:

newCertificate

After doing this correctly, a .keystore file will be generated in your home folder (in the home folder of the user who did this). This is the certificate your tomcat would use and present to any user who visit the secure site.

Configuring Tomcat

Now, we make changes in Tomcat configuration to reflect this change. Tomcat uses 2 different implementations for SSL: Apache Portable Runtime (APR) implementation and JSSE Connector implementation, provided by default with JRE (Java Runtime). Most of the users (like me) do not have APR installed by default, so following steps are valid for JSSE implementation

We now open server.xml present in $CATALINA_HOME/conf. An example <Connector> element for SSL is included by default in most server.xml that comes with Tomcat. It looks something like this:

SSLconnector

All you have to do is to uncomment this connector and add to it the location of your certificate (.keystore) that we generated and the password we used to generate it. So finally the entry for the connector looks like:

NewConnector

Also, make sure that the Non-SSL Connector (the default one) which accepts connection on 8080, should have a redirectPort attribute set to 8443 or to the port that you specified for SSL Connection in the connector above. The entry looks like:NonSSLConnector

That’s all you need to do to make sure that Tomcat starts accepting secure connections on 8443 and redirects users who attempt to access a secure page with http to https. For more details regarding each attribute of the connector, you can refer Java HTTP Connector configuration reference.

Go ahead, try it out and feel the magic that Tomcat provides you. :-) Please post any bugs, queries and corrections as comments.

Saturday, May 29, 2010

Tomcat – Container Managed Security

If you are a web developer, then I will not think twice before saying that you must have used Tomcat knowingly or unknowingly for deploying your web applications.

For me, Tomcat is a pretty basic web server, which mainly serves as a JSP/Servlet Container. Today, we explore some basic security features that are provided by the container itself. There are different ways in which this authentication can be provided. In this blog entry, we will try to understand and implement Basic & Form-based Authentication using MemoryRealm.

What’s a Realm?

According to the Tomcat specification, a Realm is a "database" of usernames and passwords that identify valid users of a web application (or set of web applications), plus an enumeration of the list of roles associated with each valid user. Obviously, there are many ways to specify the valid username-password combinations and the associated roles. We will use something known as MemoryRealm, which uses a file: tomcat-users.xml to specify this database.

Steps to Enable Authentication

  1. Change the configuration file (server.xml) of the Tomcat Server to specify the realm that you will use
  2. Change the tomcat-users.xml file to list the valid username-passwords and the associated roles
  3. Change the deployment descriptor (web.xml) for your web application to reflect security constraints needed by the application.

Step1: Change server.xml of Tomcat

The default server.xml has the UserDatabaseRealm enabled as shown below:

 serverXml

Note: This can change depending on the versions of the Tomcat, but for Tomcat 5.5 and Tomcat 6, it is the default one. We change it to use MemoryRealm by commenting the previous line and adding the following declaration as shown below:

serverXmlChanged

Step2: Change tomcat-users.xml of Tomcat

The default tomcat-users.xml file, which is present at $CATALINA_HOME/conf/tomcat-users.xml  where $CATALINA_HOME is the directory in which your Tomcat server is installed, looks like:

tomcatUsers

To this, add your own role and associate with it, some valid combination of username and password as done below:

tomcatUsersChanged

Step3: Change web.xml of your web application

So far, we have made changes in the Tomcat server itself, its time we must modify our application to reflect the security constraints that we want. To do so, we add the following to our web.xml file:

a) Security Constraints as per the need

securityConstraint

Here, We specify that in order to access any URL in our application which comes after http://{context_App}/jsp/…  should be password-protected. Also, we associate a role with it, so users associated with that role can only access these URLs now.

b) Declaring the Security Role

securityRole

c) Specifying the Type of Authentication

basicAuthntication

We tell Tomcat that we want to use BASIC authentication for our web application and the realm that we will use will use your tomcat-users.xml file. 

That’s it. All you need to do now, is to restart Tomcat and check whether this works or not. Obviously you need to create a basic web application to deploy onto the Tomcat , for which you have specified the security constraints. You can download my test web application here. (Provide a Link)…………………

This was pretty basic stuff, but it has several limitations. For one, this is not suitable for production environments and we must use FORM-based authentication instead of BASIC. Secondly, it is not a good practice to use clear-text passwords in tomcat-users.xml file. We can save the encrypted password (encrypted by any algorithm like SHA, MD2, MD5 etc) supported by the realm.

Changes to overcome limitations

1. Use Digested Passwords

Obviously, storing passwords in clear-text readable format in tomcat-users.xml cannot be considered safe or practical. In a production environment, it is essential to use some encryption to provide security. Tomcat provides us with several digest algorithms (SHA, MD2, MD5 etc) supported by MessageDigest class. To enable it, change the realm declaration in server.xml of Tomcat to the following:

memoryRealmMD5

Also, change the password you specified in tomcat-users.xml to the encrypted version of the original password, by using RealmBase class. You can find this class in catalina.jar in $CATALINA_HOME/lib directory. Use it as follows: RealmBase.digest(“password”, “MD5”, null) . Now, restart your Tomcat and test your authentication.

2. Use FORM-based Authentication

Since using BASIC authentication, you have very little control over the authentication/login method used by Tomcat and it is not considered practical for production environment. So we demonstrate another way: FORM-based authentication. The whole setup remains same, only you can provide your own custom login and error pages (with your company logo and whatever you want) instead of just popping up a window (as done by Tomcat in BASIC mode)

We will change the <login-config> element declared in your application’s web.xml as follows:

form-login-config

We will now add login.jsp and error.jsp to our application. login.jsp is used to authenticate the user: hence it would provide a form while error.jsp is the page to which user is redirected in case of an error: invalid username-password.

login.jsp will have at least a login field with name as “j_username” and password field with name as “j_password”. This must be same so that tomcat can identify the password and login fields in the form. Also the action of the form must be “j_security_check”. You can find the link to download the whole project at the end. My authentication page looks like this, which I believe is much better and safer than basic mode.

authenticate

Still, we have one limitation:

Any changes made to the file: tomcat-users.xml will be reflected only when the Tomcat server is restarted. So, if you add a new username-password combination to it, you must restart Tomcat in order to have its effect. We can also overcome this limitation by specifying the username-password and roles in a database table and using a JDBCRealm instead of MemoryRealm. You can download entire project from here.

Sunday, November 15, 2009

Deploying Web-Apps on Tomcat

Today, we are going to see various methods that can be used to deploy a web-application using Tomcat. These techniques are pretty simple and are a must for every web developer. However, most of us are only aware of a few of these.

Lets say that on your machine, Tomcat is installed at E:/Tomcat/apache-tomcat-6.0.10/. Hereafter, we will refer this location as {TOMCAT_HOME}

Also suppose that your web application is named as TestWebApp and is located at E:/MyWorkSpace/Java/TestWebApp. Hereafter, we will refer to this location as {WEBAPP_HOME}, and the output folder is named as web.

The Three Methods to deploy any web application on Tomcat are discussed below:

First Method – Copy & Paste

The simplest and the most straight-forward method to deploy any web application on Tomcat is by copying the output folder or the WAR (Web Application Archive) file of your application to webapps folder of your Tomcat installation as shown below:

a) Copy the output folder

Simply copy the output folder of your web application to {TOMCAT_HOME}/webapps/ folder. Note that you must take care that your output folder must have a folder named WEB-INF, which further contains web.xml file. This file is also known as deployment descriptor as it governs how a web application should be deployed. Now restart tomcat to see the effect.

FYI, the Tomcat Home, or the Tomcat Home page you see when you type http://localhost:8080/ is also deployed this way and the output folder is named as ROOT.

b) Copy the WAR file

First, create a WAR file by going to {WEBAPP_HOME}/web and then type:

> jar –cvf * TestWebApp.war

This will create a WAR file for you, which you have to copy to {TOMCAT_HOME}/webapps/ folder. Now, restart tomcat to see the deployed application.

Second Method – Server.xml

Another way to deploy your Web application is to add a context entry in Tomcat’s server.xml file, which can be found at {TOMCAT_HOME}/conf/server.xml

Edit this file by adding the following entry:

<Context path=”/myApp” docBase=”E:/MyWorkSpace/Java/TestWebApp/web” debug=”true” reloadable=”false” />

where myApp is now the Context for you deployed application. To see the deployed application, simply restart tomcat and access the deployed application at http://localhost:8080/myApp/

To deploy more applications, simply add one Context entry per application. Note that the path attribute should be unique for all deployed applications at one time.

Third Method – Context in an external XML file

Create a XML file containing the Context Entry for your application

<Context path=”/myApp” docBase=”E:/MyWorkSpace/Java/TestWebApp/web” debug=”true” reloadable=”false” />

You can give any name to this XML file, but a common practice is to name it in such a way that helps you identify it with the application it deploys. We name is testWebApp.xml.

All that is left now, is to copy this testWebApp.xml file to {TOMCAT_HOME}/conf/Catalina/localhost/ folder.

Restart tomcat and voila, you are done. This way, we have one XML file per application, containing the context and location for that application.

Comparing Various Methods

The first method is pretty simple and straight-forward but it restricts you to copy the output folder to Tomcat Installation, something that you would not want to do every-time or you may not have enough access rights in some cases.

On the other hand, the second method is flexible in the sense that location of the output folder of your web application is independent of your Tomcat installation. The downside is that deploying and un-deploying applications again and again can be a head-ache as you have to edit the same server.xml file again and again.

The third method rules !! It not only is flexible as its second counter-part but also it deploys applications independent of each other in the sense that each application has its own context file (xml file). In case you want to deploy some applications, while restrict some other, you simply have to move/delete the context files (xml) for the applications you do not want to deploy.

Any Comments, Suggestions or Corrections are welcome