More Books
JBoss 4.0 The Official Guide
JBoss® 4.0 The Official Guide
Table of Contents
Copyright
About the Authors
We Want to Hear from You!
Introduction
What This Book Covers
About JBoss
About Open Source
About Professional Open Source
What's New in JBoss 4.0
Chapter 1.  Installing and Building the JBoss Server
Getting the Binary Files
Installing the Binary Package
Basic Installation Testing
Booting from a Network Server
Building the Server from Source Code
Chapter 2.  The JBoss JMX Microkernel
JMX
The JBoss JMX Implementation Architecture
Connecting to the JMX Server
Using JMX as a Microkernel
The JBoss Deployer Architecture
Exposing MBean Events via SNMP
Remote Access to Services, Detached Invokers
Chapter 3.  Naming on JBoss
An Overview of JNDI
The JBossNS Architecture
Chapter 4.  Transactions on JBoss
Transaction and JTA Overview
JBoss Transaction Internals
Chapter 5.  EJBs on JBoss
The EJB Client-Side View
The EJB Server-Side View
The EJB Container
Entity Bean Locking and Deadlock Detection
Chapter 6.  Messaging on JBoss
JMS Examples
JBossMQ Overview
JBossMQ Configuration and MBeans
Specifying the MDB JMS Provider
Chapter 7.  Connectors on JBoss
JCA Overview
An Overview of the JBossCX Architecture
Configuring JDBC Datasources
Configuring Generic JCA Adaptors
Chapter 8.  Security on JBoss
J2EE Declarative Security Overview
An Introduction to JAAS
The JBoss Security Model
The JBossSX Architecture
The Secure Remote Password (SRP) Protocol
Running JBoss with a Java 2 Security Manager
Using SSL with JBoss and JSSE
Configuring JBoss for Use Behind a Firewall
Securing the JBoss Server
Chapter 9.  Web Applications
The Tomcat Service
The Tomcat server.xml File
The Engine Element
The Host Element
Using SSL with the JBoss/Tomcat Bundle
Setting the Context Root of a Web Application
Setting Up Virtual Hosts
Serving Static Content
Using Apache with Tomcat
Using Clustering
Integrating Third-Party Servlet Containers
Chapter 10.  MBean Services Miscellany
System Properties Management
Property Editor Management
Services Binding Management
Scheduling Tasks
The Log4j Service MBean
RMI Dynamic Class Loading
Chapter 11.  The CMP Engine
Example Code
The jbosscmp-jdbc Structure
Entity Beans
CMP Fields
Container-Managed Relationships
Declaring Queries
Optimized Loading
The Loading Process
Transactions
Optimistic Locking
Entity Commands and Primary Key Generation
JBoss Global Defaults
Datasource Customization
Chapter 12.  Web Services
JAX-RPC Service Endpoints
Enterprise JavaBean Endpoints
Web Services ClientsA JAX-RPC Client
Service References
Chapter 13.  Hibernate
The Hibernate MBean
Hibernate Archives
Using Hibernate Objects
Using a HAR File Inside an EAR File
The HAR Deployer
Chapter 14.  Aspect-Oriented Programming (AOP) Support
JBoss AOP: EJB-Style Services for Plain Java Objects
Why AOP?
Basic Concepts of AOP
Building JBoss AOP Applications
The JBoss AOP Deployer
Packaging and Deploying AOP Applications to JBoss
Appendix A.  The GNU Lesser General Public License (LGPL)
GNU General Public License
Appendix B.  Example Installation
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X

Using SSL with JBoss and JSSE

JBoss uses Java Secure Socket Extension (JSSE) for SSL. JSSE is bundled with JDK 1.4. To get started with JSSE, you need a public key/private key pair in the form of an X509 certificate for use by the SSL server sockets. For the purpose of this example, we have created a self-signed certificate by using the JDK keytool and included the resulting keystore file in the chap8 source directory as chap8.keystore. We created it by using the following command and input:


keytool -genkey -keystore chap8.keystore -storepass rmi+ssl -keypass rmi+ssl-keyalg RSA
 -alias chapter8 -validity 3650 -dname "cn=chapter8 example,ou=admin book,dc=jboss,dc=org"

This produces a keystore file called chap8.keystore. (A keystore is a database of security keys.) There are two different types of entries in a keystore:

  • Key entries Each entry holds very sensitive cryptographic key information, which is stored in a protected format to prevent unauthorized access. Typically, a key stored in this type of entry is a secret key or a private key accompanied by the certificate chain for the corresponding public key. The keytool and jarsigner tools only handle the latter type of entrythat is, private keys and their associated certificate chains.

  • Trusted certificate entries Each entry contains a single public key certificate that belongs to another party. It is called a trusted certificate because the keystore owner trusts that the public key in the certificate indeed belongs to the identity identified by the subject (owner) of the certificate. The issuer of the certificate vouches for this by signing the certificate.

Listing the src/main/org/jboss/chap8/chap8.keystore examples file contents by using keytool shows one self-signed certificate:

[examples]$ keytool -list -v -keystore src/main/org/jboss/chap8/chap8.keystore
Enter keystore password: rmi+ssl

Keystore type: jks
Keystore provider: SUN

Your keystore contains 1 entry
Alias name: chapter8
Creation date: Dec 16, 2004
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=chapter8 example, OU=admin book, DC=jboss, DC=org
Issuer: CN=chapter8 example, OU=admin book, DC=jboss, DC=org
Serial number: 41c23d6c
Valid from: Thu Dec 16 19:59:08 CST 2004 until: Sun Dec 14 19:59:08 CST 2014
Certificate fingerprints:
         MD5:  36:29:FD:1C:78:44:14:5E:5A:C7:EB:E5:E8:ED:06:86
         SHA1: 37:FE:BB:8A:A5:CF:D9:3D:B9:61:8C:53:CE:19:1E:4D:BC:C9:18:F2


*******************************************
*******************************************

With JSSE working and a keystore with the certificate you will use for the JBoss server, you are ready to configure JBoss to use SSL for EJB access. You do this by configuring the EJB invoker RMI socket factories. The JBossSX framework includes implementations of the java.rmi.server.RMIServerSocketFactory and java.rmi.server.RMIClientSocketFactory interfaces that enable the use of RMI over SSL-encrypted sockets. The implementation classes are org.jboss.security.ssl.RMISSLServerSocketFactory and org.jboss.security.ssl.RMISSLClientSocketFactory, respectively. There are two steps to enable the use of SSL for RMI access to EJBs. The first is to enable the use of a keystore as the database for the SSL server certificate, which you do by configuring an org.jboss.security.plugins.JaasSecurityDomain MBean. The jboss-service.xml descriptor in the chap8/ex4 directory includes the JaasSecurityDomain definition shown in Listing 8.16.

Listing 8.16. A Sample JaasSecurityDomain Configuration for RMI/SSL
<!-- The SSL domain setup -->
<mbean code="org.jboss.security.plugins.JaasSecurityDomain"
       name="jboss.security:service=JaasSecurityDomain,domain=RMI+SSL">
    <constructor>
        <arg type="java.lang.String" value="RMI+SSL"/>
    </constructor>
    <attribute name="KeyStoreURL">chap8.keystore</attribute>
    <attribute name="KeyStorePass">rmi+ssl</attribute>
</mbean>

The JaasSecurityDomain is a subclass of the standard JaasSecurityManager class that adds the notions of a keystore as well JSSE KeyManagerFactory and TRustManagerFactory access. It extends the basic security manager to allow support for SSL and other cryptographic operations that require security keys. This configuration simply loads the chap8.keystore from the Example 4 MBean SAR, using the indicated password.

The second step is to define an EJB invoker configuration that uses the JBossSX RMI socket factories that support SSL. To do this, you need to define a custom configuration for the JRMPInvoker shown in Chapter 5, "EJBs on JBoss," as well as an EJB setup that makes use of this invoker. The following code shows the jboss-service.xml descriptor that defines the custom JRMPInovker:

<mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker"
       name="jboss:service=invoker,type=jrmp,socketType=SSL">
    <attribute name="RMIObjectPort">14445</attribute>
    <attribute name="RMIClientSocketFactory">
        org.jboss.security.ssl.RMISSLClientSocketFactory
    </attribute>
    <attribute name="RMIServerSocketFactory">
        org.jboss.security.ssl.RMISSLServerSocketFactory
    </attribute>
    <attribute name="SecurityDomain">java:/jaas/RMI+SSL</attribute>
    <depends>jboss.security:service=JaasSecurityDomain,domain=RMI+SSL</depends>
</mbean>

To set up an SSL invoker, you can create an invoker binding named stateless-ssl-invoker that uses the custom JRMPInvoker. You can declare the invoker binding and connect it to EchoBean4, as shown in the following jboss.xml file:


<?xml version="1.0"?>
<jboss>
    <enterprise-beans>
        <session>
            <ejb-name>EchoBean4</ejb-name>
            <configuration-name>Standard Stateless SessionBean</configuration-name>
            <invoker-bindings>
                <invoker>
                    <invoker-proxy-binding-name>stateless-ssl-invoker<
/invoker-proxy-binding-name>
                </invoker>
            </invoker-bindings>
        </session>
    </enterprise-beans>

    <invoker-proxy-bindings>
        <invoker-proxy-binding>
            <name>stateless-ssl-invoker</name>
            <invoker-mbean>jboss:service=invoker,type=jrmp,socketType=SSL</invoker-mbean>
            <proxy-factory>org.jboss.proxy.ejb.ProxyFactory</proxy-factory>
            <proxy-factory-config>
            <client-interceptors>
                <home>
                    <interceptor>org.jboss.proxy.ejb.HomeInterceptor</interceptor>
                    <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                    <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                    <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                </home>
                <bean>
                    <interceptor>org.jboss.proxy.ejb.StatelessSessionInterceptor</interceptor>
                    <interceptor>org.jboss.proxy.SecurityInterceptor</interceptor>
                    <interceptor>org.jboss.proxy.TransactionInterceptor</interceptor>
                    <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
                </bean>
            </client-interceptors>
            </proxy-factory-config>
        </invoker-proxy-binding>
    </invoker-proxy-bindings>
</jboss>

The Example 4 code is located under the src/main/org/jboss/chap8/ex4 directory of the book examples. This is another simple stateless session bean with an echo method that returns its input argument. It is hard to tell when SSL is in use unless it fails, so you can run the Example 4 client in two different ways to demonstrate that the EJB deployment is in fact using SSL. You need to start the JBoss server, using the default configuration, and then run Example 4b as follows:

[examples]$ ant -Dchap=chap8 -Dex=4b run-example
...
run-example4b:
     [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
     [echo] Waiting for 15 seconds for deploy...
...
     [java] Exception in thread "main" java.rmi.ConnectIOException:
error during JRMP connection establishment; nested exception is:
     [java]     javax.net.ssl.SSLHandshakeException: sun.security.validator.
ValidatorException: No trusted certificate found
...

The resulting exception is expected, and it is the purpose of the 4b version of the example. Note that the exception stack trace has been edited to fit into the book format, so you can expect some differences. The key item to notice about the exception is that it clearly shows that you are using the Sun JSSE classes to communicate with the JBoss EJB container. The exception is saying that the self-signed certificate you are using as the JBoss server certificate cannot be validated as signed by any of the default certificate authorities. This is expected because the default certificate authority keystore that ships with the JSSE package includes only well-known certificate authorities such as VeriSign, Thawte, and RSA Data Security. To get the EJB client to accept your self-signed certificate as valid, you need to tell the JSSE classes to use your chap8.keystore as its truststore. (A truststore is a keystore that contains public key certificates used to sign other certificates.) To do this, you run Example 4, using -Dex=4 rather than -Dex=4b to pass the location of the correct truststore, using the javax.net.ssl.trustStore system property:

[examples]$ ant -Dchap=chap8 -Dex=4 run-example
...
run-example4:
     [copy] Copying 1 file to /tmp/jboss-4.0.1/server/default/deploy
     [echo] Waiting for 5 seconds for deploy...
...
     [java] Created Echo
     [java] Echo.echo()#1 = This is call 1

This time the only indication that an SSL socket is involved is the SSL handshakeCompleted message. This comes from the RMISSLClientSocketFactory class as a debug-level log message. If you did not have the client configured to print out log4j debug-level messages, there would be no direct indication that SSL was involved. If you note the runtimes and the load on your system CPU, you see that there definitely is a difference. SSL, like SRP, involves the use of cryptographically strong random numbers that take time to seed the first time they are used. This shows up as high CPU utilization and startup times.

One consequence of this is that if you are running on a system that is slower than the one used to run the examples for this book, such as when running example 4b, you might see an exception similar to the following:

javax.naming.NameNotFoundException: EchoBean4 not bound
   at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer
...

The problem is that the JBoss server has not finished deploying the sample EJB in the time the client allowed. This is due to the initial setup time of the secure random number generator used by the SSL server socket. If you see this problem, you can simply rerun the example or increase the deployment wait time in the Chapter 8 build.xml Ant script.