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

Wednesday, September 21, 2011

Tomcat - using Realm to protect access to JSF application (part 2 of 2)

Note: below description uses Eclipse Indigo, Tomcat 7.0.28, MyFaces 2.1.7
 
Requirements:
  • understanding basics of Tomcat's Realm
You will learn:
  • how to define users and roles in own web applications (JSF 2.0 as example)
  • how to use encrypted passwords for realm users instead od plain text
In the previous post I described how to configure access to Tomcat's server administration application using Tomcat's Realm elements. The whole thing boiled down to write a few lines of text in server.xml file. But how does it look like when we have to do it from scratch in our application?

Step 1. Let's create very simple JSF application which has only 3 pages:
  • /index.html - main page with two buttons navigating into two pages:
  • /unrestrictedPage.xhtml - page always accessible and visible to anyone
  • /restricted/restrictedPage.xhtml - page and directory available only for valid users
The complete application structure will look like:



Step 2: we have to add a privilleged user named admin with password adminpass who belongs to role privillegedUsers (You can choose any user login, password and role name). Just simply add this line:
<user username="admin" password="adminpass" roles="privillegedUsers" />
into [tomcat directory]\conf\tomcat-users.xml file.

Step 3: configuring application. We have to modify web.xml of our sample application by adding following text:
<web-app>
...
    <security-role>
        <description>
              All persons belong to that role have access to restricted application area.
        </description>
        <role-name>privillegedUsers</role-name>
    </security-role>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Restricted</web-resource-name>
            <url-pattern>/faces/restricted/*</url-pattern>
            <url-pattern>/restricted/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>privillegedUsers</role-name>
        </auth-constraint>
    </security-constraint>

    <login-config>
        <auth-method>BASIC</auth-method>
        <realm-name>Restricted access</realm-name>
    </login-config>
...
</web-app>
First we defined a role named privillegedUsers - the same we put in tomcat-users.xml file above. Second we have to defined prottected parts of our application, by providing proper URL pattern. Please note that we have two entries here: /restricted/* - everything in this directory is protected in case someone typed this part manually in browser's address bar,  /faces/restricted/* - JSF adds "faces" prefix when navigating between pages, so the URL is a little bit different and we have to watch for this also. After that we have to define a role which is allowed to access to the protected parts. This is privillegedUsers role defined earlier. At the end we have to define the way how the authentication is done - the simplest way is BASIC, which displays predefined form with credentials.

Now we are ready to deploy our application on Tomcat and run it. It should look like this:


when we try to access to restricted area. In order to do this we have to put credentials for user defined in step 2 (admin, adminpass).

Note: there is a little trick here, for the button "Restricted area" - see index.xhtml page source code:
<h:commandButton value="Resricted area" action="/restricted/restrictedPage.xhtml?faces-redirect=true" />
<h:commandButton value="Unrestricted area" action="/unrestrictedPage.xhtml" />
Because JSF internally by default makes forward to other page, browser is unaware what has happened and display URL from one step back. In such case our URL security patterns will not match anything, and restrictedPage.xhtml will be displayed without asking for login and password! In order to make protection work we have to perform full redirection for that action in order to force browser to fetch target URL and display it. For JSF applications it is better to use filters or Spring Security in order to avoid such dirty tricks.

Encrypted passwords.

As You probably have seen, passwords vor valid users are stored inside tomcat-users.xml file as a plain text. There is a possibility to store them in encrypted form, using MD5. Here is what needs to be done:

Step 1: using Eclipse modify Tomcat server.xml and its <Realm> atrribute into:
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" digest="MD5"/>
Step 2: in web.xml change <auth-method> from BASIC to DIGEST

Step 3: for user admin and his previous password adminpass we have to generate its md5 equivalent using Tomcat's digest.bat file (located in [tomcat directory]\bin folder) :

digest.bat -a md5 admin:"Restricted access":adminpass

"Restricted access" is a realm name taken from <auth-method> tag from web.xml. Those names must match, if name contains spaces, it must be surrounded with "".


Step 4: using Eclipse modify Tomcat's tomcat-users.xml file:
<user username="admin" password="db7bc05adcf611fc779f32a4e680cc01" roles="privillegedUsers" /> 
where password was taken as a result of executing command from step 3.

-------------------------------------------
Download source files:

Note: make sure that Java, Eclipse and Tomcat are properly installed and configured for running the project (additional configuration may be required if different directories are used).

Eclipse complete sample project is here (with all required libraries).

Tuesday, September 13, 2011

Tomcat - change default application, protecting access to web applications using Realm (part 1 of 2)

Note: below description uses Eclipse Indigo, Tomcat 7.0.28,

Requirements:
  • installed Java (description here)
  • installed and configured Eclipse (description here)
  • installed and confiured Tomcat for the Eclipse (description here)
You will learn:
  • how to change default Tomcat application
  • how to allow users access to Tomcat's server administration application using Tomcat's Realm

Let's assume that You have Tomcat which is configured to work in Eclipse. When You start Tomcat (using Eclipse or standard scripts from Tomcat's distribution) and type in the browser URL http://localhost:8080, You will see Tomcat's default application:


This application is located in the [tomcat directory]\webapps\ROOT folder. If You want to change this page, just edit content of file index.jsp and index.html. If You want to completely remove this application, just remove complete ROOT folder.
Removing is not the best choice, because Tomcat is shipped with a special applications for server administration. You can access those applications using links in red square. Try to click on any link - You should see screen with login and password prompt:


Those parts are protected using Tomcat Realm. What is Realm? Realm is a set of valid users (defined by user name and password) and roles where those users belong. The idea is to configure access to web application only for valid users from certain roles. But where are those users and roles stored? It depends on a implementation of a realm - they can be stored in database, in LDAP, or in xml file. Tomcat's server administration application uses xml file to define users' access. Let's try to set up some users able to start that application.

Step 1: using Eclipse open server.xml from the Servers, and make sure that entry <Realm classname="org.apache.catalina.realm.UserDatabaseRealm" resourcename="UserDatabase"></Realm> exsits between <Engine> tags, outside <Host&gt tags - it means that this realm will be used for all hosts and all applications on that  hosts:


Step 2: using Eclipse open tomcat-users.xml from the Servers and add an entry for the user who will be able to access Tomcat's server administration application:


By default UserDatabaseRealm uses [tomcat directory]\conf\tomcat-users.xml file to load users and their roles into memory on server startup. In order to allow defined users to access administration application, they need to belong to roles named manager-status, manager-gui and admin-gui. After changes made, restart Tomcat server and try to access Tomcat's administration application giving username and password from tomcat-users.xml file. If everything was set up OK, You should see mentioned applications.

You may wonder why we used here roles named manager-status or manager-gui or admin-gui. Those role names come from Tomcat's server administration application specific settings, stored in the web.xml file. In the next post I will show how to protect own application (JSF2 application will be used as an example) and how to define own roles.

Wednesday, August 03, 2011

SSL in Tomcat under Eclipse (part 2 - certificate from CA)

Requirements:
  • You should be able to generate self signed SSL certificate and integrate it into Tomcat, as described in previous post.
You will learn:
  • how to obtain and install a real SSL certificate from well known Certificate Authority (CA)
In the previous post I described the complete procedure of generating self signed SSL certificate and integrating it into Tomcat. In this post I would like to focus on the example with real certificate obtained from CA - I will use Thawte as example.

Note: let's assume that You created an application which is going to be visible under the following URL: http://www.myapp.com.

Step 1: generating self signed certificate for domain www.myapp.com.

This is exactly the same step to step 1 in previous post. You have to execute the following command:

keytool -genkey -alias myappcert -keyalg RSA -keystore myapp.keystore

Step 2: Generate Certificate Signing Request (CSR).

You have to generate a special request, which will be send to the CA. You have to execute command:

keytool -certreq -keyalg RSA -alias myappcert -file certreq.csr -keystore myapp.keystore

Generated request is saved as a certreq.csr file, which will be send to CA. CA will use this file to generate certificate signed by them.

Important: You have to use exactly the same alias (in this example: myappcert) for step 1 and step 2.

Step 3: Getting certificate from CA.

Usually certificate are delivered in PKCS#7 or X.509 format. For the first one, the file with certificate will have .p7b extension, for the second one - .cer. Sometimes You can get such certificate also by email as a pure text - for the X.509 format, certificate will be placed between tags -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----, for PKCS#7 certificate will be placed between tags -----BEGIN PKCS7----- and -----END PKCS7-----. Then You have to copy the certificate content (including those begin/end tags!) and save this as a .cer or .p7b file (You can use Notepad for that). Now You are ready to import Your signed certificate.

Step 4: importing signed certificate.

a) as a .p7b (PKCS#7) format:
Acording to the Thawte, when You obtained Your certificate as a .p7b file, You need only one command to import and install this certificate in Your keystore:

keytool -import -alias myappcert -trustcacerts -file signed_cert.p7b  -keystore myapp.keystore

where signed_cert.p7b is a signed certificate obtained from CA.

b) as a .cer (X.509) format:
According to the Thawte, when You obtained Your certificate as .cer file,  You need to download Primary and Secondary Intermediate CAs and import them. They are delivered as .p7b format (i.e. intermediate.p7b). I should import them first, using command:

keytool -import -trustcacerts -alias intermediatecerts  -file intermediate.p7b -keystore myapp.keystore

and then import my certificate (it is in .cer file signed_cert.cer) using this command:

keytool -import -trustcacerts -alias myappcert -file signed_cert.cer -keystore myapp.keystore

where signed_cert.cer is a signed certificate obtained from CA.

Problem and workaround:
Both above ways seems to be simple, but... when I was buying some time ago a web SSL certificate from Thawte, I receive certificate as a pure text in e-mail. Certificate was in X.509 format (I had tags ----BEGIN/END CERTIFICATE-----). I created a signed_cert.cer file from that e-mail content. Then I tried to install intermediate certificates like it was described in Thawte documentation. Unfortunately it didn't work. The first command for importing intermediate certificates failed with error:

keytool error: java.lang.Exception: Input not an X.509 certificate

It seems that keytool does not work with .p7b format (I used JDK 1.6.0_16), so I expect that even if I get my certificate as .p7b file (complete, without need to import intermediate certificates as in a) subpoint) it will also not work. I took a .p7b file with intermediate certificates, opened it under Windows, and for each certificate found inside i exported it as a X.509 DER certificate, giving each file .cer extension. So I had three .cer (X.509) files: signed_cert.cer, thawte_primary.cer, thawte_secondary.cer. Now I had to import intermediate certificates and after that import my signed certificate with those commands:

keytool -import -trustcacerts -alias primary -file thawte_primary.cer -keystore myapp.keystore
keytool -import -trustcacerts -alias secondary -file thawte_secondary.cer.cer -keystore myapp.keystore
keytool -import -trustcacerts -alias myappcert -file signed_cert.cer -keystore myapp.keystore

Now import was OK. So the general workaround rule (if there are any troubles) is: get all needed certificates in X.509 form, import intermediate certificates (if any required) and import Your signed certificate at the end.

Important: You have to use exactly the same alias (in this example: myappcert) like You used in step 1 and step 2, except for importing intermediate certificates - You can use whatever alias You like.

Step 5: copy Your myapp.keystore file into Tomcat's /conf directory

Step 6: modify Tomcat configuration to use SSL certificate

It is exactly the same as step 3 in previous post.


That's all.

Monday, August 01, 2011

SSL in Tomcat under Eclipse (part 1 - self signed certificate)

Requirements:
  • installed Java (description here)
  • installed and configured Eclipse (description here)
  • installed and configured Tomcat for the Eclipse (description here)
You will learn:
  • how to set up Tomcat for SSL connection using self signed certificate under Eclipse
When You want to secure Your application SSL is the most natural choice. In order to make Your application be recognized as trusted by browser, You can by a buy a certificate from well known certificate authority (CA), which will be generated for the domain Your application uses. If You do not care about being recognized as trusted service, but instead You just want to encrypt the data exchanged between server and client's browser, You can use Your own self signed SSL certificate. In this post I will show how to generate such SSL certificate and how to set up Tomcat (from the Eclipse level) to use generated certificate.

Note: let's assume that You created an application which is going to be visible under the following URL: http://www.myapp.com.

Step 1: generating self signed certificate for domain www.myapp.com.

Go into Your Java bin directory (i.e C:\Development\Java\bin). Then open Windows console (under Windows Vista/7 open the console with Administrator right) and type in command:

keytool -genkey -alias myappcert -keyalg RSA -keystore myapp.keystore

where myappcert is the name of the certificate being generated and myapp.keystore is a file where certificate will be stored. You will be asked about the password for created the myapp.keystore file. Type in "mypass", press Enter and type it again and press Enter again. Then You will be asked for some details about You:



Please note that for the first question about first and last name I gave answer www.myapp.com. This is very important - this name (known as CN - Common Name) will be used for the checking if certificate on the page we visit was generated for the same URL which we typed in in the browser.
At the end You will be asked for the password for the newly created certificate. The password must be the same as one used for myapp.keystore file ("mypass"). Do not type antyhing, just press Enter to use the same password. Your myapp.keystore file containing myappcert certificate is ready.

Step 2: copy Your myapp.keystore file into Tomcat's /conf directory

Step 3:  modify Tomcat configuration to use SSL certificate.

Make sure that Your Tomcat is configured with Eclipse and works OK without SSL (start Tomcat from Eclipse and type in http://localhost:8080 in the browser). Stop Tomcat if it is running. Then open server.xml file form the "Servers" view:



and locate default element for standard HTTP connections (marked red). Then add additional element for the SSL connection (next to existing one):
<Connector
        SSLEnabled="true"
        clientAuth="false"
        keyAlias="myappcert"
        keystoreFile="conf/myapp.keystore"
        keystorePass="mypass"
        maxThreads="200"
        port="8081"
        scheme="https"
        secure="true"
        sslProtocol="TLS"
 /> 

Please note that next to some specific SSL settings, we set the location of the keystore file, the password for that file and certificate name to be use. SSL connection uses port 8081, where normal HTTP connection
uses port 8080.

Note 1: all modification of server.xml file were done from Eclipse level, using "Servers" view. If You want to use Eclipse WTP for starting Tomcat (like I do so far) You can't edit this file from elsewhere. Eclipse WTP overrides original Tomcat configuration files by files visible under "Servers" - changes done outside Eclipse will not be visible for WTP.

Note 2: I added element specific for SSL next to existing element for standard non encrypted HTTPS connections. This is second issue directly connected with Eclipse WTP - when You remove standard connector for HTTP, Eclipse will close Tomcat after a time set in "Timeouts" section in the Tomcat settings:



Some people try to extend the timeout time into long period, but still after this period Eclipse kills Tomcat process, as if Tomcat was not properly started in the required time. Unfortunately there is no way to set timeout into ifinite time - the only way to fix this under WTP is to leave standard HTTP element in Tomcat's server.xml file.

Step 4: that's all. Tomcat is configured to work with SSL. 

Try to enter the URL: https://localhost:8081. If You see Tomcat's page, everything works OK (You can see certificate warning - You Need to add security exception for that certificate). Of course You can still open the same Tomcat page by standard HTTP (You have two elements), just enter http://localhost:8080 URL.

Wednesday, July 27, 2011

Tomcat OutOfMemoryError: Heap space/PermGen space

Note: below description uses Tomcat 7.0.28

Have You ever seen such error in Your logs? Probably yes. It simply means that available memory for Tomcat was consumed and nothing left. To be precise: available memory for JVM which Tomcat uses to run.

What causes this error? It can be caused by memory leaks in the application or the applications has big requirements "by design", even if there are no memory leaks. For the first case You should use some profiling tools to find and fix memory leaks - perhaps this might help without need to change memory settings for Tomcat JVM. If You are sure that Your application has no memory leaks, the only way is to increase memory used by Tomcat JVM. See below how to do that - please note that I described modifying Tomcat memory settings when it is installed as a service under Windows OS.

32-bit Windows
The main problem here is that 32-bit OS is able to see no more than 3,2GB of RAM, even if You have 4GB or more physically installed. This is upper limit of memory that can be use - in theory. However, in practise You will not be able to use more than 1 to 1,5GB of RAM for Tomcat's JVM - the rest of memory is used by OS itself and installed software.

64-bit Windows
Let's assume that You need to assign more than 1,5GB of RAM for Tomcat JVM. Therefore You need 64-bit OS with at least 4GB of RAM (for example 64-bit Windows Professional supports up to 192GB of RAM). Of course You must also use 64-bit JDK - when You use 32-bit JDK under 64-bit OS, You will again face the limit of 3,2GB RAM. You also must use 64-bit version of Tomcat (as it contains Windows service wrapper to use with 64-bit JVMs on 64-bit Windows platforms). Below You will find complete list of all needed steps:

Step 1: make sure You are using 64-bit Windows OS. 

Step 2: install 64-bit JDK and set $JAVA_HOME to the installation directory. 

Step 3: download .zip file with 64-bit Tomcat for Windows (file: apache-tomcat-[version]-windows-x64.zip). 

Step 4: extract Tomcat and go into Tomcat's /bin directory.

Step 5: open service.bat file and locate the line with --JvmMS and --JvmMX parameters, and modify it with new values memory, eg:

%EXECUTABLE%" //US//%SERVICE_NAME% ++JvmOptions "-Djava.io.tmpdir=%CATALINA_BASE%\temp" ++JvmOptions "-XX:MaxPermSize=1024m" --JvmMs 2048 --JvmMx 4096

Note: PermSize is set in different way than heap which has predefined JvmMS and JvmMX flags.

Step 6: open Windows console with administrator rights, then go into Tomcat /bin and execute command:

service.bat install tomcat6

Step 7: start service with command:

net start tomcat6

Note 1: You can skip point 5 and execute directly point 6. After that just start tomcat6w.exe which is a GUI tool for managing the service. You can set memory values there.

Note 2: as an alternative to above steps, You can download Tomcat service installer (file: apache-tomcat-[version].exe) which performs service installation, and then use tomcat6w.exe tool for tune memory settings.

That's all. Your Tomcat service should use provided memory settings.

Monday, May 04, 2009

Installing and configuring Tomcat for Eclipse

Note: below description uses Tomcat 7.0.40.

Probably You always wanted to write your own web-based application in Java (ok, read: writing another Facebook-like portal and live in luxury in Dubai to the end of Your life ;-)). Of course it is possible, but before that inevitable moment occurs, You have to do much more simple thing - configure the environment for developing web applications (unless You are headmaster in Your own company and someone else does it for you...).

So let's look at how to configure Apache Tomcat which is professionally defined as the servlet container (i.e. for JSP). I will show how to configure it under Eclipse.

Recall that so far we have managed to install Java and set up Eclipse to work with it. It is time for Tomcat. 

Step 1: download the Tomcat binary distribution (core version as a .zip file) from here

Step 2: Unpack the .zip from step 1 to the C:\Development\Tomcat directory. We should get something like this:


Step 3: Open Eclipse IDE and the Java EE perspective (Window menu -> Open Perspective -> Other -> Java EE). This will be the default perspective for our work. Using this perspective, at the bottom in the "Servers" tab we add a new server:


Step 4: Configure the new server. Select the type of the server (Tomcat 7) and leave the name set to localhost:

Step 5: Further configuration of the new server. Select the server's installation directory (in our case C:\Development\Tomcat) and Java virtual machine which will be used - in this case it will be the same virtual machine which we configured to work with Eclipse (see this article).

After pressing Next, Eclipse will display a window asking You to add some web applications to the newly defined server. Ignore this by pressing Finish.

Step 6: Basic configuration of a server. Open server configuration panel by double click on the server name on Servers tab.


We allow the Eclipse to manage Tomcat installation and use wtpwebapps  folder (in Tomcat directory structure) for deploying our applications. In addition we change the way Tomcat publish applications on the server - each application will have a separate xml configuration file in Tomcat (so-called "context" file).

Tomcat is ready and configured to work. We can start and stop it using the icons on the right side in the "Servers" tab. The results of these operations (logs), are visible in the "Console" tab.