Self-signed' certificate
Tomcat site comes with great instructions for setting up SSL. The documentation can be found at http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html.
In a typical production environment, SSL is handled by a web server such as Apache, which unencrypts the requests and forwards them on to Tomcat. As a result, usually Tomcat doesn't need to be concerned with SSL. However, it is possible to set things up so that you talk to Tomcat directly rather than through a web server, and in this situation SSL needs to be set up for secure communication between browsers (clients) and Tomcat. When you set up SSL, a 'certificate' is created that identifies your server by IP address.
Certificate Authorities like Verisign exist to verify to clients that your server is who your certificate says it is. If you run an eCommerce site, you would definitely want your server to be registered with a Certificate Authority so that clients know they can trust that your server to be the server they think it is.
However, this type of registration can be fairly involved and expensive. What should you do if you just want to make sure that certain communication between a client browser and your Tomcat server is encrypted? A quick solution is to create a 'self-signed' certificate. If you do this, clients can't really trust that you are who you say you are, but communication between a client and your server will be encrypted.
Using Basic authentication and HTTPS (w/ self-signed certificates) in Java
Tomcat site comes with great instructions for setting up SSL. The documentation can be found at http://tomcat.apache.org/tomcat-5.5-doc/ssl-howto.html.
In a typical production environment, SSL is handled by a web server such as Apache, which unencrypts the requests and forwards them on to Tomcat. As a result, usually Tomcat doesn't need to be concerned with SSL. However, it is possible to set things up so that you talk to Tomcat directly rather than through a web server, and in this situation SSL needs to be set up for secure communication between browsers (clients) and Tomcat. When you set up SSL, a 'certificate' is created that identifies your server by IP address.
Certificate Authorities like Verisign exist to verify to clients that your server is who your certificate says it is. If you run an eCommerce site, you would definitely want your server to be registered with a Certificate Authority so that clients know they can trust that your server to be the server they think it is.
However, this type of registration can be fairly involved and expensive. What should you do if you just want to make sure that certain communication between a client browser and your Tomcat server is encrypted? A quick solution is to create a 'self-signed' certificate. If you do this, clients can't really trust that you are who you say you are, but communication between a client and your server will be encrypted.
Using Basic authentication and HTTPS (w/ self-signed certificates) in Java
1. Client Authentication is in practice only used for B2B type applications.
2. In some cases we may even be okay with not authenticating the server on the client end during SSL handshake, for sake of:
o simplicity (no certificate signing infrastructure is required) and
o performance (we only use SSL for encryption and not for server authentication).
This approach is of self-signed certificate which the server can sign for itself and client will by-pass server authentication.
3. We first need to configure web server for SSL. Tomcat currently operates only on JKS, PKCS11 or PKCS12 format keystores.
4. We can use the JDK keytool to generate self-signed certificate for the host running tomcat as shown below:
The example.keystore is then generated and is in JKS (Java Key Store) format.
5. Copy it to the Tomcat root directory say C:\Program Files\Apache Software Foundation\Tomcat 6.0 path.
6. The final step is to configure your secure socket in the $CATALINA_HOME/conf/server.xml file, where $CATALINA_HOME represents the directory into which you installed Tomcat 6.
NOTE: You can refer to the http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html for more configuration options.
With the above settings you can verify that browsing to https://localhost:8443 returns the splash page of tomcat home.
7. We will also make sure that tomcat has a role named "manager" and some user associated with the role. We can edit the tomcat_users.xml for that:
8. Now, we can enforce that a certain URL pattern for our web application always requires https access. To do this, we need to edit the web.xml of the web application:
With the above configuration, we have Basic authentication and HTTPS enabled for all resources accessed by the URL pattern /secure/XYZ/*.
So even if you try to access the resource at /secure/XYZ/* using http then tomcat will redirect you to the page using https scheme and thus enforce secure use. Since we also use the Basic authentication so browser client will prompt you entering user credentials.
9. If you are using API based http client access from say a J2SE client (using apache commons httpclient 3.x) then you will need to set the credentials for the realm MY_SECURE_REALM (which defines the Authentication Scope on the web server) in the Http header.
Also you will need to use the org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory to be able to by-pass the agent authentication on client side. Apache commons httpclient comes with this contrib code which is included with the source distro but is not bundled in the jar file. So you will need to pull the source out from contrib/ssl path and use it in your project.
Basically you will need to check if the uri in use has scheme type of https then associate the EasySSLProtocolSocketFactory as the protocol handler for the scheme.
The way it works is, EasySSLProtocolSocketFactory in turn uses the EasyX509TrustManager (again from contrib/ssl) to just do a agent certificate validity from and to time validation (so that the ceritificate is not expired and is not before the validity start date). As long as the certificate in use by the agent is valid the EasyX509TrustManager will be okay to bypass doing any authentication for the self-signed certificate for the agent.
That completes the simple discourse on how to use Basic authentication with HTTPS (using self-signed certificate for the server end).
2. In some cases we may even be okay with not authenticating the server on the client end during SSL handshake, for sake of:
o simplicity (no certificate signing infrastructure is required) and
o performance (we only use SSL for encryption and not for server authentication).
This approach is of self-signed certificate which the server can sign for itself and client will by-pass server authentication.
3. We first need to configure web server for SSL. Tomcat currently operates only on JKS, PKCS11 or PKCS12 format keystores.
4. We can use the JDK keytool to generate self-signed certificate for the host running tomcat as shown below:
$ keytool -genkey -alias tomcat -keyalg RSA -keystore example.keystore Enter keystore password: secret Re-enter new password: secret What is your first and last name? [Unknown]: localhost What is the name of your organizational unit? [Unknown]: What is the name of your organization? [Unknown]: <My Company Name> What is the name of your City or Locality? [Unknown]: <City> What is the name of your State or Province? [Unknown]: <State> What is the two-letter country code for this unit? [Unknown]: <Country Code> Is CN=localhost, OU=Unkown, O=<My Company Name>, L=<City>, ST=<State>, C=<Country> correct? [no]: yes Enter key password for(RETURN if same as keystore password): <Enter>
The example.keystore is then generated and is in JKS (Java Key Store) format.
5. Copy it to the Tomcat root directory say C:\Program Files\Apache Software Foundation\Tomcat 6.0 path.
6. The final step is to configure your secure socket in the $CATALINA_HOME/conf/server.xml file, where $CATALINA_HOME represents the directory into which you installed Tomcat 6.
<Connector protocol="org.apache.coyote.http11.Http11Protocol" port="8443" minSpareThreads="5" maxSpareThreads="75" enableLookups="true" disableUploadTimeout="true" acceptCount="100" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" keystoreFile="./example.keystore" keystorePass="secret" clientAuth="false" sslProtocol="TLS"/>
NOTE: You can refer to the http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html for more configuration options.
With the above settings you can verify that browsing to https://localhost:8443 returns the splash page of tomcat home.
7. We will also make sure that tomcat has a role named "manager" and some user associated with the role. We can edit the tomcat_users.xml for that:
<?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="manager"/> <user username="admin" password="admin" roles="manager"/> </tomcat-users>
8. Now, we can enforce that a certain URL pattern for our web application always requires https access. To do this, we need to edit the web.xml of the web application:
<security-constraint> <display-name>some name for service</display-name> <web-resource-collection> <web-resource-name>My Service</web-resource-name> <description/> <url-pattern>/secure/XYZ/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>HEAD</http-method> <http-method>PUT</http-method> <http-method>OPTIONS</http-method> <http-method>TRACE</http-method> <http-method>DELETE</http-method> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> <user-data-constraint> <description/> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>MY_SECURE_REALM</realm-name> </login-config> <security-role> <description>manager api can use this role.</description> <role-name>manager</role-name> </security-role>
With the above configuration, we have Basic authentication and HTTPS enabled for all resources accessed by the URL pattern /secure/XYZ/*.
So even if you try to access the resource at /secure/XYZ/* using http then tomcat will redirect you to the page using https scheme and thus enforce secure use. Since we also use the Basic authentication so browser client will prompt you entering user credentials.
9. If you are using API based http client access from say a J2SE client (using apache commons httpclient 3.x) then you will need to set the credentials for the realm MY_SECURE_REALM (which defines the Authentication Scope on the web server) in the Http header.
HttpState state = new HttpState(); state.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, "MY_SECURE_REALM"), new UsernamePasswordCredentials(user, passwd));
Also you will need to use the org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory to be able to by-pass the agent authentication on client side. Apache commons httpclient comes with this contrib code which is included with the source distro but is not bundled in the jar file. So you will need to pull the source out from contrib/ssl path and use it in your project.
Basically you will need to check if the uri in use has scheme type of https then associate the EasySSLProtocolSocketFactory as the protocol handler for the scheme.
if (uri.getScheme().equals("https")) { Protocol easyhttps = new Protocol(uri.getScheme(), new EasySSLProtocolSocketFactory(), uri.getPort()); Protocol.registerProtocol("https", easyhttps); }
The way it works is, EasySSLProtocolSocketFactory in turn uses the EasyX509TrustManager (again from contrib/ssl) to just do a agent certificate validity from and to time validation (so that the ceritificate is not expired and is not before the validity start date). As long as the certificate in use by the agent is valid the EasyX509TrustManager will be okay to bypass doing any authentication for the self-signed certificate for the agent.
That completes the simple discourse on how to use Basic authentication with HTTPS (using self-signed certificate for the server end).
0 comments:
Post a Comment