Designing and Developing Secure Java EE Applications using GlassFish Security

October 6, 2010

Java / J2EE

«»

Deploying the application client module in the Application Client Container


The application client module can be a first layer Java SE application which directly
communicates with the EJB container and uses services like transaction and security
management of EJB container through the Application Client Container.


When it comes to software structure an application client is not different from
a simple Java SE application. It has a main method, which is the software entry
point and we can access different Java EE services simply with annotation or using
deployment descriptors.


The following listing shows the main method for our application client, which
invokes the Conversion Session Bean and prints the result.



public class Main {
@EJB
private static ConversionRemote conversionBean;
public static void main(String[] args) {
System.out.println(conversionBean.toInch(10));
}
}


You may ask how this application can use injection and access an EJB instance.
The secret is, as we saw in Chapter 1, hiding in another type of container called the
Application Client Container. We deploy an application client module in the ACC
and later execute it in the machine either as Java Web Start application or simply
using GlassFish-provided scripts. When we run this application the following
procedure takes place:



  1. Application client (launched using Web Start or directly) results in the ACC
    trying to inject the secured EJB.

  2. The EJB method requires authentication, so GlassFish calls the default
    CallbackHandler to get user login.

  3. The default CallbackHandler, which is a simple username and password
    collecting dialog, appears on the client’s screen.

  4. The collected username and password are sent back to application server for
    authentication and authorization.

  5. After a successful authentication, the method invocation goes through.


This procedure happens even if we do not add any single line of configuration to our
EJB module deployment descriptor or Application Client deployment descriptor. The
following figure shows more detail about the interaction between different modules
when a secure EJB is called from an application client.


The default configuration for application client authentication is summarized in the
following table:



All of these measures are configurable either through the Application Client
deployment descriptor or the EJB deployment descriptor or the ACC deployment
descriptor. The following table shows which attributes are configurable through each
one of these deployment descriptors.



Two of the deployment descriptors included in the above table are specific to each
vendor and may differ between different application servers. The only standard
descriptor is application-client.xml, which is a part of the application client
standard. This descriptor is placed inside the META-INF directory of the client
application and contains information like which resources our application is using,
how the application is accessing these resources, and finally definitions of the
callback handler we want to use to collect user credentials.


The following figure shows default the CallbackHandler, which is fired to collect
username and password before the container lets the application invoke a method
with security constraint.



We can change the default CallbackHandler in application-client.xml by
specifying a new Callbackhandler. The new callback should implement the
javax.security.auth.callback.CallbackHandler. The following snippet
shows the callback-handler element in application-client.xml.



<callback-handler>
book.glassfish.security.chapter3.SwingCallbackHandler
</callback-handler>


We can use a programmatic way to provide the ACC with username and
password instead of using the callback mechanism to have more control over
the authentication procedures. To conduct programmatic login we can use
com.sun.appserv.security.ProgrammaticLogin class to login before we access
any EJB method which has security constraints, defining security measures for
communication over IIOP.


We can use the GlassFish-specific deployment descriptor for EJB modules to define
several types of configuration elements. We can use one set of these elements to
define security measures for communication between the EJB container and the
clients over IIOP (Internet Inter-Orb Protocol).


The super element for the IOR security is ior-security-config, which includes the
following sub elements:



  • The transport-config for specifying transport security

  • The sas-context for specifying the caller propagation options

  • The as-context for specifying the authentication method, the security realm
    we want to use for authentication.


Following snippet shows what we should include in the EJB deployment
descriptor to get SSL transport security along with username and password-based
authentication using the LDAPRealm we defined in Chapter 2.



<ior-security-config>
<transport-config>
<integrity>required</integrity>
<confidentiality>required</confidentiality>
<establish-trust-in-target>Required
</establish-trust-in-target>
<establish-trust-in-client>none</establish-trust-in-client>
</transport-config>
<as-context>
<auth-method>username_password</auth-method>
<realm>LDAPRealm</realm>
<required>true</required>
</as-context>
<sas-context>
<caller-propagation>supported</caller-propagation>
</sas-context>
</ior-security-config>


Starting from the top, this snippet instructs the EJB container’s IIOP listener to use
SSL for data transmission to ensure the integrity and confidentiality of data which
is transferred between client and server. Other possible values for integrity and
confidentiality elements are Supported and None, which means server supports
SSL if requested by clients or it does not provide them even if the client asks for data
integrity and confidentiality.


We can have SSL mutual authentication by changing the value of establish-trustin-
target and establish-trust-in-client to required. This way the client will
authenticate itself to the server using its digital certificate and in the same way the
server will authenticate itself to the client using the digital certificate we specified for
IIOP listeners.


When using mutual authentication, we should ensure that the trust store of the client
trusts the certificate of the server and the trust store of the server trusts the certificate
of the client. To achieve this we should:



  1. Add the digital certificate of the client’s certificate issuer to the server
    trust store.

  2. Include the digital certificate of the server’s certificate issuer to the client’s
    trust store.


Later in the code snippet we have the as-context element that we can use to specify
which authentication method and security realm we want to use for authenticating
clients that need to invoke a secure method of an EJB. The only supported
authentication method is USERNAME_PASSWORD.


The last element is sas-context. We can use it to specify whether EJB container
accepts propagated caller identities or not. Possible values are Supported, Required,
and None.


Configuring Application Client Container security


The Application Client Container hosts a Java SE layer application that interacts with
the EJB container of the application server using IIOP. Each instance of the container
can only host one instance of the client application and can be configured for that
client application instance.



When we want to run a client application deployed in GlassFish
we can either use Java Web Start or the script file provided in the
GlassFish bin directory. Command format for using the script file is
as follow:
./appclient -client /opt/dev/Conversion-app-client.
jar -xml /opt/dev/sun-acc.xml
It means that we want to launch the Conversion-app-client.jar
using a configuration file named sun-acc.xml.


The sun-acc.xml structure follows the schema defined in the http://www.sun.
com/software/appserver/dtds/sun-application-client-container_1_2.dtd
and allows us to configure every aspect of the ACC. The following shows the content
of sun-acc.xml, which has both authentication and transport security configured.



<client-container>
<target-server name=”localhost” address=”127.0.0.1″ port=”3700″>
<security>
<ssl cert-nickname=”s1as”
ssl2-enabled=”false”
ssl2-ciphers=”-rc4,-rc4export,-rc2,-rc2export,-des,
-desede3″
ssl3-enabled=”true”
ssl3-tls-ciphers=”+rsa_rc4_128_md5,
-rsa_rc4_40_md5,+rsa3_des_sha,+rsa_des_sha,
-rsa_rc2_40 _md5,-rsa_null_md5,-rsa_des_56_sha,
-rsa_rc4_56_sha”
tls-enabled=”true”
tls-rollback-enabled=”true”/>
<cert-db path=”ignored” password=”ignored”/>
<!– not used –>
</security>
<auth-realm name=”LDAPRealm”
classname=”com.sun.enterprise.security.auth.realm.ldap.LDAPRealm”>
<property name=”directory”
value=”ldap://127.0.0.1:1389″/>
<property name=”base-dn” value=” dc=example,dc=com “/>
<property name=”search-bind-password” value=”123456″/>
<property name=”jaas-context” value=”ldapRealm”/>
</auth-realm>
</target-server>
<client-credential user-name=”james” password=”james”/>
</client-container>


Starting from the top, we are instructing the container to use a certificate identified
by client nickname. Later on we will see how we can specify which keystore and
trust store we want our client container to use when we launch our application.


All other properties of the ssl element specify which SSL version and cipher suites
are available to the ACC to choose from. During the negotiation between server and
client to establish an SSL session, the strongest cipher suite supported by both server
and client is selected.


In addition to configuring the transport security we can configure the authentication
mechanism for ACC in order to let ACC collect the identification information and
send them back to server when required. Following the security element we have the
auth-realm element which specifies the authentication realm that ACC must use to
conduct the authentication.


You should know all of these properties as we discussed them in great detail
in Chapter 2. The only thing that you should remember is the fact that this
configuration has nothing to do with the LDAP realm we configured in the server.
This configuration affects only the client container instance running in the client
machine and using this particular sun-acc.xml file.



The Application Client Container process exists in the clients machine
and anything we configure using the sun-acc.xml affects the client
machines and has nothing to do with the server or other clients, which
run another instance of the application client.


Next we have the client-credential element which we can use to specify the
default client credential that ACC sends to server instead of collecting the username
and password. This element ensures that a single principal is used for all invocation
without end users knowing about it.


Using SSL always bring out the issue of keystore and trust store which the
application requires using during the SSL handshake and SSL session. There is no
vendor-specific way to pass the trust and key store information to Java runtime and
rather we can use the JVM environment variables to set these values.


When JVM starts and needs to use SSL, it looks for some environment variables to
initiate the SSL session. These variables are included in the following table.



In Linux, we can use the following command to export these variables before
launching the application client using the appclient script.



export VMARGS=”-Djavax.net.ssl.keyStore=key-store-path -Djavax.net.ssl.
trustStore= trust-store-path -Djavax.net.ssl.keyStorePassword=key-storepassword
-Djavax.net.ssl.trustStorePassword=trust-store-password”


For Microsoft Windows we can use the set command to set VMARGS value
as follows:



set VMARGS=”-Djavax.net.ssl.keyStore=key-store-path -Djavax.net.ssl.
trustStore=trust-store-path -Djavax.net.ssl.keyStorePassword=key-storepassword
-Djavax.net.ssl.trustStorePassword=trust-store-password”


To create a working pair of certification stores we can follow the same steps we
followed to create keystore and trust store for GlassFish application server. Using
the same certificate issuer will guarantee that GlassFish will accept the certificate
provided by the client and the client will accept the certificate provided by GlassFish.


Now that we have set the required runtime arguments for JVM we can run the client
application and be assured about data confidentiality and integrity. The sample
application for this chapter is included in the source code archive of the book.


Summary


In this chapter we studied Java EE security in action and developed a secure Java EE
application with all of standard modules including EJB, Web, and application clients.


We studied how we can secure EJBs using annotation and then use a web frontend
to use the secure EJBs after the user provides correct identification information. We
developed a client application to access the secure EJB and later on we studied how
we can use SSL and mutual authentication between the application client module
and EJB container.


In the next two chapters we will look at GlassFish security independent of
the Java EE security and what measures we should consider to have a safe
GlassFish installation.

email

«»

Comments

comments