Skip Headers
Oracle® Application Server Containers for J2EE Standalone User's Guide
10g Release 2 (10.1.2)
Part No. B14361-02
  Go To Documentation Library
Library
Go To Product List
Product
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

3 Configuring Security

OC4J security employs a user manager to authenticate and authorize users and groups that attempt to access a J2EE application. User managers differ in performance and are employed based on the security you require. Confidentiality through encryption is supplied with SSL.

This chapter describes the following topics:

For a broader description of Oracle Application Server security, see the Oracle Application Server Security Guide and the Oracle Application Server Containers for J2EE Security Guide.

3.1 Overview of Security Functions

OC4J security is based on a two-step process. First, a user or group attempting to access a J2EE application is authenticated, and then it is authorized. Authentication and authorization are provided under various user managers, such as the JAZNUserManager and XMLUserManager classes. The JAZNUserManager class is the default and offers the best security. The XMLUserManager is the simplest method for security. The JAZNUserManager leverages the OracleAS JAAS Provider as the security infrastructure for OC4J by using either the Lightweight Directory Access Protocol (LDAP)-based or the XML-based provider type. The XMLUserManager is configured using a file, so the passwords are visible.

See "Plugging In a User Manager" for details on the OracleAS JAAS Provider, provider types, and user managers. Also, see the Oracle Application Server Containers for J2EE Security Guide for details on the OracleAS JAAS Provider and provider types.


Note:

The default user manager was changed from the XMLUserManager to the JAZNUserManager.

Authentication and authorization, along with OC4J confidentiality, are introduced below:

3.2 Authentication

Authentication verifies that the identity and credentials of a user are valid. The J2EE application determines which user can use the application. However, it is the user manager, employing the user name and password, that verifies the user's identity based on information in the user repository. Authentication is distinct from authorization, which is the process of giving a user access to a J2EE application, based on his identity.

OC4J security authenticates two types of clients: HTTP and Enterprise JavaBeans (EJBs). This section describes each of these along with setting up users and groups.

3.2.1 Specifying Users and Groups

OC4J supports the definition of users and groups—either shared by all deployed applications or specific to a given application.

  • Shared users and groups are listed in the user repository, whose location is specified in the global config/application.xml file.

  • Application-specific users and groups are listed in the application-specific user repository, whose location is specified in the orion-application.xml file of that application.

The way you define users and groups depends on what user manager you employ. For example, because the Oracle Application Server Java Authentication and Authorization Service (JAAS) Provider(OracleAS JAAS Provider) uses roles instead of groups, the JAZNUserManager XML-based user repository, jazn-data.xml, has a different structure from the XMLUserManager user repository, principals.xml. In addition, in a JAZNUserManager user repository, passwords are encrypted, unlike in principals.xml.

The following sections offer examples of how to specify users and groups under the JAZNUserManager and XMLUserManager classes. See "Plugging In a User Manager" for additional details on these classes.

3.2.1.1 Example: Specifying Users and Groups in jazn-data.xml

The following XML from the JAZNUserManager user repository configuration file, jazn-data.xml, shows how to define OracleAS JAAS Provider roles (groups) and users. It defines a group named allusers and a user named guest.

<role>
  <name>allusers</name>
  <members>
   <member>
    <type>user</type>
    <name>guest</name>
   </member>
  </members>
</role>

Unlike the XML from the XMLUserManager user repository configuration file, principals.xml, you can encrypt the password under the JAZNUserManager.

<user>
  <name>guest</name>
  <description>The default user</description>
  <credentials>wEE6aA==</credentials>
</user>

Note:

See the Oracle Application Server Containers for J2EE Security Guide for more information on setting up the jazn-data.xml file.

3.2.1.2 Example: Specifying Users and Groups in principals.xml

The following XML from the principals.xml file (the user repository configuration file for the XMLUserManager class) shows how to define a group named allusers and a user named guest with password welcome. The guest user is made a member of the allusers group.

If you want to use the XMLUserManager class instead of the JAZNUserManager class, you must modify the global application.xml file, if modifying for all applications, or the orion-application.xml file, if using the XMLUserManager class only for a specific application. Add the following line:

<principals path="./principals.xml" /> 

where the path points to the location of the principals.xml file. Also, you must remove or comment out the <jazn provider> element in this file.


Note:

You can hide the password through password indirection. See the Oracle Application Server Containers for J2EE Security Guide for a description of password indirection.

<principals> 
 <groups> 
  <group name="allusers"> 
   <description>Group for all normal users</description> 
   <permission name="rmi:login" /> 
   <permission name="com.evermind.server.rmi.RMIPermission" /> 
  </group> 
....other groups... 
 </groups> 
 <users> 
  <user username="guest" password="welcome"> 
   <description>Guest user</description> 
   <group-membership group="allusers" /> 
  </user> 
 </users> 
</principals> 

3.2.2 Authenticating HTTP Clients

OC4J requests the client to authenticate itself when accessing protected URLs. You can achieve authentication through a user name and password, or in the case of SSL, through an SSL certificate. Although in most cases where authentication is required, the user is prompted to enter a user name and password. If you decide to use an SSL certificate to authenticate the client, see "Confidentiality Through SSL" for directions on how to set up your client certificate and server keystore.

3.2.3 Authenticating EJB Clients

When you access EJBs in OC4J, you must pass valid credentials to this server.

  • Standalone clients define their credentials in the jndi.properties file, either deployed with the EAR file or in the InitialContext object.

  • Servlets or JavaBeans running within OC4J pass their credentials within the InitialContext object, which is created to look up the remote EJBs.

3.2.3.1 Setting JNDI Properties

If the client exists within the same application as the target, or the target exists within its parent, you do not need a JNDI properties file. If not, you must initialize your JNDI properties either within a jndi.properties file, in the system properties, or within your implementation, before the JNDI call. The following sections discuss these three options:

3.2.3.1.1 No JNDI Properties

A servlet that exists in the same application with the target bean automatically accesses the JNDI properties for the node. Therefore, accessing the EJB is simple, because no JNDI properties are required.

//Get the Initial Context for the JNDI lookup for a local EJB
InitialContext ic = new InitialContext();
//Retrieve the Home interface using JNDI lookup
Object empObject = ic.lookup("java:comp/env/employeeBean");

This is also true if the target bean is in an application that has been deployed as this application's parent. To specify parents, use the -parent option of the admin.jar command when deploying the originating application.

3.2.3.1.2 JNDI Properties File

If you are setting the JNDI properties within the jndi.properties file, set the properties as follows. Ensure that this file is accessible from the CLASSPATH.

Factory

java.naming.factory.initial=
com.evermind.server.ApplicationClientInitialContextFactory

Location

The ORMI default port number is 23791, which you can modify in j2ee/home/config/rmi.xml. Therefore, set the URL in the jndi.properties, in one of two ways:

java.naming.provider.url=ormi://hostname/application-name

- or -

java.naming.provider.url=ormi://hostname:23791/application-name

Security

When you access EJBs in OC4J, you must pass valid credentials to this server. Standalone clients define their credentials in the jndi.properties file deployed with the code of the client.

java.naming.security.principal=username
java.naming.security.credentials=password
3.2.3.1.3 JNDI Properties Within Implementation

Set the properties with the same values, but with different syntax. For example, JavaBeans running within the container pass their credentials within the InitialContext, which is created to look up the remote EJBs.

To pass JNDI properties within the Hashtable environment, set these as shown below:

Hashtable env = new Hashtable(); 
env.put("java.naming.provider.url", "ormi://myhost/ejbsamples"); 
env.put("java.naming.factory.initial", 
      "com.evermind.server.ApplicationClientInitialContextFactory"); 
env.put(Context.SECURITY_PRINCIPAL, "guest"); 
env.put(Context.SECURITY_CREDENTIALS, "welcome"); 
Context ic = new InitialContext (env); 
Object homeObject = ic.lookup("java:comp/env/employeeBean");

// Narrow the reference to a TemplateHome.
EmployeeHome empHome =
	 (EmployeeHome) PortableRemoteObject.narrow(homeObject,
                                                   EmployeeHome.class);

3.2.3.2 Using the Initial Context Factory Classes

For most clients, set the initial context factory class to ApplicationClientInitialContextFactory. If you are not using a logical name defined in the <ejb-ref> in your XML configuration file, then you must provide the actual JNDI name of the target bean. In this case, you can use a different initial context factory class, the com.evermind.server.RMIInitialContextFactory class.

Example 3-1 Servlet Accessing EJB in Remote OC4J Instance

The following servlet uses the JNDI name for the target bean: /cmpapp/employeeBean. Thus, this servlet must provide the JNDI properties in an RMIInitialContext object, instead of the ApplicationClientInitialContext object. The environment is initialized as follows:

  • The INITIAL_CONTEXT_FACTORY is initialized to a RMIInitialContextFactory.

  • Instead of creating a new InitialContext, it is retrieved.

  • The actual JNDI name is used in the lookup.

Hashtable env = new Hashtable();
env.put(Context.PROVIDER_URL, "ormi://myhost/cmpapp");
env.put(Context.SECURITY_PRINCIPAL, "admin");
env.put(Context.SECURITY_CREDENTIALS, "welcome");
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.evermind.server.rmi.RMIInitialContextFactory");

Context ic = 
new com.evermind.server.rmi.RMIInitialContextFactory().
getInitialContext(env);

Object homeObject = ic.lookup("/cmpapp/employeeBean");

// Narrow the reference to a TemplateHome.
EmployeeHome empHome =
(EmployeeHome) PortableRemoteObject.narrow(homeObject,
EmployeeHome.class);

3.3 Authorization

Authorization is the process of granting or denying a user access to a J2EE application based on its identity. Authorization is distinct from authentication, which is the process of verifying that a user is valid.

Specify authorization for users and groups in the J2EE and OC4J-specific deployment descriptors. The J2EE deployment descriptor is where you specify the access rules for using logical roles. The OC4J-specific deployment descriptor is where you map logical roles to actual users and groups, which are defined in a user repository.

The following sections describe how to define users, groups, and roles:

3.3.1 Specifying Logical Roles in a J2EE Application

Specify the logical roles that your application uses in the XML deployment descriptors. Depending on the application component type, update one of the following with the logical roles:

  • web.xml for the Web component

  • ejb-jar.xml for the EJB component

  • application.xml for the application

In each of these deployment descriptors, the roles are defined by an XML element named <security-role>.

Example 3-2 EJB JAR Security Role Definition

The following steps describe the XML necessary to create a logical role named VISITOR in the ejb-jar.xml deployment descriptor.

  1. Define the logical security role, VISITOR, in the <security-role> element.

    <security-role> 
     <description>A role for every user</description> 
     <role-name>VISITOR</role-name> 
    </security-role>
    
    
  2. Define the bean and methods that this role can access in the <method-permission> element.

    <method-permission> 
     <description>VISITOR role needed for CustomerBean methods</description> 
     <role-name>VISITOR</role-name> 
     <method> 
      <ejb-name>customerbean</ejb-name> 
      <method-name>*</method-name> 
     </method> 
    </method-permission>
    

3.3.2 Mapping Logical Roles to Users and Groups

Map logical roles defined in the application deployment descriptors to actual users and groups defined in a user repository. The mapping is specified in the OC4J-specific deployment descriptor with a <security-role-mapping> element. Figure 3-1 illustrates this mapping.

Figure 3-1 Mapping Logical Roles to Users and Groups Defined in jazn-data.xml

Description of Figure 3-1  follows
Description of "Figure 3-1 Mapping Logical Roles to Users and Groups Defined in jazn-data.xml"


Note:

The security role mapping layer, either defined in the principals.xml or jazn-data.xml file, is bypassed if the following conditions are true:
  • The name of the security role and group (or roles, as in the case of jazn-data.xml) are the same.

  • No security role mapping is specified.


Example 3-3 Mapping Logical Role to Actual Role

This example maps the logical role VISITOR to the allusers group in the orion-ejb-jar.xml file. Any user that can log in as part of this group is considered to have the VISITOR role and can therefore execute the methods of customerbean. This role is mapped to the allusers group, which is defined in the User Manager configuration file—the jazn-data.xml file.

<security-role-mapping name="VISITOR"> 
 <group name="allusers" /> 
</security-role-mapping> 

Note:

You can map a logical role to a single group or to several groups.

3.4 Plugging In a User Manager

Any user manager class providing OC4J security is an implementation of the com.evermind.security.UserManager interface. This includes any custom user managers you create. User manager classes manage users, groups, and passwords with such methods as createUser(), getUser(), and getGroup(). Table 3-1 lists the user managers that you can employ in OC4J security.

Table 3-1 User Managers and Their User Repositories Available to OC4J

User Manager User Repository

oracle.security.jazn.oc4j.JAZNUserManager

  • using the XML-based provider type—jazn-data.xml

  • using the LDAP-based provider type—OID

com.evermind.server.XMLUserManager

principals.xml

Custom user manager

user-provided user repository


By default, OC4J reads the user names, groups, and passwords from the JAZNUserManager user repository, jazn-data.xml. In order for OC4J to employ any user manager, you must specify the name of the user manager class in one of the following XML files:

The following sections describe how to configure each User Manager type:

3.4.1 Using the JAZNUserManager Class

The primary purpose of the JAZNUserManager class is to leverage the OracleAS JAAS Provider as the security infrastructure for OC4J. For a complete description of the OracleAS JAAS Provider, see the Oracle Application Server Containers for J2EE Security Guide.

By integrating the OracleAS JAAS Provider with OC4J, the following benefits can be achieved:

  • Single Sign-on (SSO)/mod_osso integration

  • SSL/mod_ossl integration

  • OID integration (using the LDAP-based provider type)

  • Fine-grained access control using Java2 permissions

  • run-as identity support, delegation support (from servlet to EJB)

  • Secure file-based storage of passwords (using the XML-based provider type)

Use the JAZNUserManager class if you want OC4J security that has secure, centralized storage, retrieval, and administration of OracleAS JAAS Provider data. This data consists of realm (user and roles) and OracleAS JAAS Provider policy (permissions) information. Figure 3-2 illustrates the architecture of OC4J security under the JAZNUserManager class.

The JAZNUserManager class can use two types of OracleAS JAAS Providers for OC4J security. Use the provider type that is appropriate for your environment:

  • LDAP-based

    For centralized storage of information in a directory. The user repository is OID.

  • XML-based

    For lightweight storage of information in an XML file. The user repository is the jazn-data.xml file.

Figure 3-2 OC4J Security Architecture Under the JAZNUserManager Class

Description of Figure 3-2  follows
Description of "Figure 3-2 OC4J Security Architecture Under the JAZNUserManager Class"

In OC4J, you can configure your application(s) to use the JAZNUserManager class by adding the <jazn> or <user-manager> element in your OC4J-specific configuration file (config/application.xml or orion-application.xml).

3.4.1.1 Using the JAZNUserManager Class with the LDAP-Based Provider Type

The LDAP-based provider type delegates user and group management functionality to the Delegated Administrative Service (DAS) from OID.

The following examples from an OC4J-specific configuration file have OC4J employ the JAZNUserManager class as the user manager with the LDAP-based provider type.

<jazn provider="LDAP" default-realm="sample_subrealm"
location="ldap://myoid:389" />

- or -

<user-manager class="oracle.security.jazn.oc4j.JAZNUserManager">
<property name="provider.type" value="LDAP" />
<property name="realm.default" value="sample_subrealm" />
<property name="ldap.service"  value="ldap://myoid:389" />
</user-manager>

Notes:

If you specify both the <user-manager> element and the <jazn> element, then the <jazn> element is ignored.

3.4.1.2 Using the JAZNUserManager Class with the XML-Based Provider Type

The XML-based provider type is a fast, lightweight implementation of the OracleAS JAAS Provider API. This provider type uses XML to store user names and encrypted passwords.

The following examples from an OC4J-specific configuration file have OC4J employ the JAZNUserManager class as the user manager with the XML-based provider type. The user repository is located at .../j2ee/home/jazn/config/jazn-data.xml. Because there is only one realm in the data file, the specification of realm.default is not needed.

<jazn provider="XML"
location=".../j2ee/home/config/jazn-data.xml" />

- or -

<user-manager class="oracle.security.jazn.oc4j.JAZNUserManager">
<property name="provider.type" value="XML" />
<property name="xml.store.fs.jazn"
value=".../j2ee/home/config/jazn-data.xml" />
</user-manager>

Notes:

If you specify both the <user-manager> element and the <jazn> element, then the <jazn> element is ignored.

3.4.2 Using the XMLUserManager Class

The XMLUserManager is a file-based security model, where all of your users, roles, groups, and passwords are stored in principals.xml. This is not secure as your passwords could be in the clear.

However, if you want to use the XMLUserManager class instead of the JAZNUserManager class, you must modify the global application.xml file, if modifying for all applications, or the orion-application.xml file, if using the XMLUserManager class only for a specific application. Add the following line:

<principals path="./principals.xml" /> 

where the path points to the location of the principals.xml file. Also, you must remove or comment out the <jazn> element in this file. If you do not remove or comment out the <jazn> element, then whichever element is specified first is the User Manager for the applications. For example, if you have the following:

<principals path="./principals.xml" /> 
<jazn provider="XML"
location=".../j2ee/home/config/jazn-data.xml" />

In this case, the <principals> element appears first, so the XMLUserManager is the security manager.

3.4.3 Creating Your Own User Manager

If none of the user managers supplied by OC4J are suitable for your specific user authentication needs, then you can create your own user manager and configure OC4J to use it.

To create your own user manager, complete the following steps:

  1. Write a custom user manager.

    Your custom user manager class must implement the com.evermind.security.UserManager interface. Table 3-2 describes the methods of this interface.

    Table 3-2 Methods of the UserManager Interface

    Method Description

    void addDefaultGroup (java.lang.String name)

    Adds a group to the set of default groups, of which all users of the user manager are members.

    • java.lang.String name - the name of the group being added to the default group

    Group createGroup (java.lang.String name)

    Creates a new group. If the group already exists, a java.lang.InstantiationException is thrown.

    • java.lang.String name - the name of the new group

    User createUser (java.lang.String username, java.lang.String password)

    Creates a new user.

    • java.lang.String username - the new user name

    • java.lang.String password - the new user password

    User getAdminUser()

    Returns the default admin user or null if there is none.

    User getAnonymousUser()

    Returns the default anonymous user or null if none exists.

    java.util.Set getDefaultGroups()

    Returns the set of default groups for the user manager.

    Group getGroup(java.lang.String name)

    Returns the group with the specified name or null if none exists.

    • java.lang.String name - the name of the specified group

    int getGroupCount()

    Returns the number of users contained in the user manager. Throws UnsupportedOperationException if not supported.

    java.util.List getGroups (int start,int max)

    Returns a list of groups (between the specified indexes) contained in the user manager. Throws UnsupportedOperationException if not supported.

    UserManager getParent()

    Returns the parent manager of the user manager.

    User getUser (java.lang.String username)

    Returns the user with the specified user name or null if there is no match.

    User getUser (java.lang.String issuerDN, java.math.BigInteger serial)

    Returns the user associated with this certificate or null if either certificates are not supported or there is no user associated with this certificate.

    User getUser (java.security.cert.X509Certificate certificate)

    Returns the user associated with this certificate or null if either certificates are not supported or there is no user associated with this certificate.

    int getUserCount()

    Returns the number of users contained in this manager. Throws UnsupportedOperationException if not supported.

    java.util.List getUsers (int start,int max)

    Returns a list of users (between the specified indexes) contained in this manager. Throws UnsupportedOperationException if not supported.

    void init (java.util.Properties properties)

    Instantiates the user manager with the specified settings. Throws java.lang.InstantiationException if any errors occur.

    boolean remove(Group group)

    Removes the specified group from the user manager and returns true if the operation is successful.

    boolean remove(User user)

    Removes the specified user from the user manager and returns true if the operation is successful.

    void setParent (UserManager parent)

    Sets the parent user manager if one exists. This method is called only on a nested user manager.

    A user manager can delegate work to its parent user manager.


  2. Plug the user manager into your application.

    For a single application, specify the custom user manager in the <user-manager> element of the orion-application.xml file. For all applications in the server, specify the custom user manager in the <user-manager> element of the config/application.xml file.

  3. Define your users and groups.

    See "Specifying Users and Groups".

  4. Create security constraints in your Web application.

    See "Authorization".

Example 3-4 Using the DataSourceUserManager Class

The following example of the DataSourceUserManager class is a custom user manager and it implements the UserManager interface. Within its methods, the DataSourceUserManager class manages the users in a database specified by the DataSource interface.

To configure a custom user manager, you specific the classname in the class attribute of the <user-manager> element in either the global application.xml file or the orion-application.xml file. Then, you can specify input parameters and values through the name/value attributes of one or more <property> elements.

For our DataSourceUserManager example, it requires that the table name and columns are defined in the <property> element name/value pairs. This example sets up the following input parameters:

  • Data source that specifies the database where the tables reside

  • Table for user names and passwords

  • Table for user and group association

A typical registration of the user manager for an application can be specified in orion-application.xml, as follows:

<user-manager class="com.evermind.sql.DataSourceUserManager">
	 <property name="dataSource" value="jdbc/OracleCoreDS" />
	 <property name="table" value="j2ee_users" />
	 <property name="usernameField" value="username" />
	 <property name="passwordField" value="password" />
	 <property name="groupMembershipTableName" value="second_table" />
	 <property name="groupMembershipGroupFieldName" value="group" />
	 <property name="groupMembershipUserNameFieldName" value="userId" />
</user-manager>

The <user-manager> property elements define the input parameters into the UserManager class. It assumes that the tables that these refer to already exist in the database.

The user manager is a hierarchical implementation with a parent-child relationship. The parent of the DataSourceUserManager class is the default file-based XMLUserManager class, which uses the principals.xml user repository. However, you can change the parent with the setParent() method. The sample DataSourceUserManager class invokes parent.getGroups() to retrieve all the available groups from its parent, the XMLUserManager.

3.5 Confidentiality Through SSL

OC4J supports Secure Socket Layer (SSL) communication between the client and a standalone OC4J, using HTTPS.

The following sections document SSL in detail:

3.5.1 Overview of Using SSL for OC4J Standalone

The following sections describe security features and discuss how to use them with OC4J standalone:

3.5.1.1 Overview of SSL Keys and Certificates

In SSL communication between two entities, each entity (or at least the server) has an associated public key and a private key. During communication, each entity uses its own private key, together with the public key of the other party, to ensure that they can communicate with each other. If one entity encrypts data using its private key, then the other party can decrypt the data by only by using the public key of the originating entity. If one entity encrypts data using the public key of the other party, then that party can decrypt the data only by using its own private key.

Each key is a number, with the private key of an entity being kept secret by that entity, and the public key of an entity being publicized to any other parties with which secure communication might be necessary.

A certificate is a digitally signed statement from a recognized issuer that verifies the public key of an entity. Such an issuer is referred to as a certificate authority (CA). An issued certificate is typically associated with a root certificate. This association, or "chaining", of certificates establishes a chain of trust. An issuer might have its own root certificate, and will chain any certificates it issues to its own root certificate.

Functionally, a certificate acts as a container for keys, holding private keys (as applicable), public keys, and associated signatures. A single certificate file can contain an entire chain of certificates.

A keystore is used for storage of certificates, including the certificates of all trusted parties. Through its keystore, an entity, such as OC4J, can authenticate itself to other parties.

A keystore is a java.security.KeyStore instance that you can create and manipulate using the keytool utility, provided with the Sun Microsystems JDK. Go to the following site for information about keytool:

http://java.sun.com/j2se/1.3/docs/tooldocs/win32/keytool.html

During secure communication between the client and OC4J, the following functionality is executed:

  • The link (all communications) between the two is encrypted.

  • OC4J is authenticated to the client through a security challenge and response. A "secret key" is securely exchanged and used for the encryption of the link.

  • Optionally, if OC4J is in client-authentication mode, the client is authenticated to OC4J.

3.5.1.2 Using Certificates with OC4J Standalone

The steps for using keys and certificates for SSL communication in OC4J are as follows. These are server-level steps, typically executed prior to deployment of an application that will require secure communication, perhaps when you first set up OC4J.

  1. Use keytool to generate a private key, public key, and unsigned certificate.You can place this information into either a new keystore or an existing keystore.

  2. Obtain a signature for the certificate, using either of the following two approaches.

    • You can generate your own signature by using keytool to "self-sign" the certificate. This is appropriate if your only clients will trust you as, in effect, your own certificate authority.

    • You can obtain a signature from a recognized certificate authority through the following steps:

    1. Using the certificate from Step 1, use keytool to generate a certificate request, which is a request to have the certificate signed by a certificate authority.

    2. Submit the certificate request to a certificate authority.

    3. Receive the signature from the certificate authority and import it into the keystore, again using keytool. In the keystore, the signature will be matched with the associated certificate.

The process for requesting and receiving signatures is up to the particular certificate authority you use. You can go to the Web site of any certificate authority for information. Any browser should have a list of trusted certificate authorities. Here are the Web addresses for VeriSign and Thawte (acquired by VeriSign), for example:

http://www.verisign.com/
http://www.thawte.com/

In addition, Oracle provides a certificate authority, where each certificate is recognized only by Oracle applications. The Oracle Certificate Authority (OCA) allows customers to create and issue certificates for themselves and their users, although these certificates would likely be unrecognized outside a customer's organization without prior arrangements. See the Oracle Application Server Security Guide for information about OCA.

3.5.2 Configuration of OC4J for SSL

For secure communication between a client and OC4J, configuration is required on OC4J standalone. You are required to provide a certificate on the client-side only if you configure client-authentication.

In the http-web-site.xml file of OC4J (or other Web site XML file, as appropriate), you must specify appropriate SSL settings under the <web-site> element.

  1. Turn on the secure flag to specify secure communication, as follows:

    <web-site ... protocol="http" secure="true" ... >
       ...
    </web-site>
    
    

    Setting secure="true" specifies that the HTTP protocol is to use an SSL socket.

  2. Use the <ssl-config> subelement and its keystore and keystore-password attributes to specify the directory path and password for the keystore, as follows:

    <web-site ... secure="true" ... >
       ...
       <ssl-config keystore="path_and_file" keystore-password="pwd" />
    </web-site>
    
    

    The <ssl-config> element is required whenever the secure flag is set to "true".

    The path_and_file value can indicate either an absolute or relative directory path and includes the file name.


    Note:

    You can hide the password through password indirection. See Oracle Application Server Containers for J2EE Security Guide for a description of password indirection.

  3. Optionally, turn on the needs-client-auth flag, an attribute of the <ssl-config> element, to specify that client authentication is required, as follows:

    <web-site ... secure="true" ... >
       ...
       <ssl-config keystore="path_and_file" keystore-password="pwd" 
                   needs-client-auth="true" />
    </web-site>
    
    

    This step sets up a mode where OC4J accepts or rejects a client entity for secure communication, depending on its identity. The needs-client-auth attribute instructs OC4J to request the client certificate chain upon connection. If the root certificate of the client is recognized, then the client is accepted.

    The keystore specified in the <ssl-config> element must contain the certificates of any clients that are authorized to connect to OC4J through HTTPS.

  4. Optionally, specify each application in the Web site as shared. The shared attribute of the <web-app> element indicates whether multiple bindings (different Web sites, or ports, and context roots) can be shared. Supported values are "true" and "false" (default).

    Sharing implies the sharing of everything that makes up a Web application, including sessions, servlet instances, and context values. A typical use for this mode is to share a Web application between an HTTP site and an HTTPS site at the same context path, when SSL is required for some but not all of the communications. Performance is improved by encrypting only sensitive information, rather than all information.

    If an HTTPS Web application is marked as shared, then instead of using the SSL certificate to track the session, the cookie is used to track the session. This is beneficial in that the SSL certificiate uses 50K to store each certificate when tracking it, which sometimes results in an "out of memory" problem for the session before the session times out. This could possibly make the Web application less secure, but might be necessary to work around issues such as SSL session timeouts not being properly supported in some browsers.

  5. Optionally, set the cookie domain if shared is true and the default ports are not used. When the client interacts with a Web server over separate ports, the cookie believes that each separate port denotes a separate Web site. If you use the default ports of 80 for HTTP and 443 for HTTPS, the client recognizes these as two different ports of the same Web site and creates only a single cookie. However, if you use non-default ports, the client does not recognize these ports as part of the same Web site and will create separate cookies for each port, unless you specify the cookie domain.

    Cookie domains track the client's communication across multiple servers within a DNS domain. If you use non-default ports for a shared environment with HTTP and HTTPS, set the cookie-domain attribute in the <session-tracking> element in the orion-web.xml file for the application. The cookie-domain attribute contains the DNS domain with at least two components of the domain name provided.

    <session-tracking cookie-domain=".oracle.com" />
    

Example 3-5 HTTPS Communication With Client Authentication

The following configures a Web site for HTTPS secure communication with client authentication:

<web-site display-name="OC4J Web Site" protocol="http" secure="true" >
   <default-web-app application="default" name="defaultWebApp" />
   <access-log path="../log/default-web-access.log" />
   <ssl-config keystore="../keystore" keystore-password="welcome" 
              needs-client-auth="true" />
</web-site>

Only the portions in bold are specific to security. The protocol value is always "http" for HTTP communication, whether or not you use secure communication. A protocol value of http with secure="false" indicates HTTP protocol; http with secure="true" indicates HTTPS protocol.

Then, configure the news application to accept both HTTP and HTTPS connections:

<web-app application="news" name="news-web" root="/news" shared="true" /> 

This Web site uses the default port numbers for HTTP and HTTPS communication. If it did not, you would also add the cookie-domain attribute.

<session-tracking cookie-domain=".oracle.com" />

For more information about elements and attributes of the <web-site>, <web-app>, and <session-tracking> elements, see the XML Appendix in the Oracle Application Server Containers for J2EE Servlet Developer's Guide.

Example 3-6 Creating an SSL Certificate and Configuring HTTPS

The following example uses keytool to create a test certificate and shows all of the XML configuration necessary for HTTPS to work. To create a valid certificate for use in production environments, see the keytool documentation.

  1. Install the correct JDK

    Ensure that JDK 1.3.x is installed. This is required for SSL with OC4J. Set the JAVA_HOME to the JDK 1.3 directory. Ensure that the JDK 1.3.x JAVA_HOME/bin is at the beginning of your path. This may be achieved by doing the following:

    UNIX

    $ PATH=/usr/opt/java130/bin:$PATH
    $ export $PATH
    $ java -version
    java version "1.3.0"
    
    

    Windows

    set PATH=d:\jdk131\bin;%PATH%
    
    

    Ensure that this JDK version is set as the current version in your Windows registry. In the Windows Registry Editor under HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft/Java Development Kit, set 'CurrentVersion' to 1.3 (or later).

  2. Request a certificate

    1. Change directory to ORACLE_HOME/j2ee

    2. Create a keystore with an RSA private/public keypair using the keytool command. In our example, we generate a keystore to reside in a file named 'mykeystore', which has a password of '123456' and is valid for 21 days, using the 'RSA' key pair generation algorithm with the following syntax:

    keytool -genkey -keyalg "RSA" -keystore mykeystore -storepass 123456 -validity 21
    
    

    Where:

    • the keystore option sets the filename where the keys are stored

    • the storepass option sets the password for protecting the keystore

    • the validity option sets number of days the certificate is valid

    The keytool prompts you for more information, as follows:

    keytool -genkey -keyalg "RSA" -keystore mykeystore -storepass 123456 -validity 21
    
    What is your first and last name?
      [Unknown]:  Test User
    What is the name of your organizational unit?
      [Unknown]:  Support
    What is the name of your organization?
      [Unknown]:  Oracle
    What is the name of your City or Locality?
      [Unknown]:  Redwood Shores
    What is the name of your State or Province?
      [Unknown]:  CA
    What is the two-letter country code for this unit?
      [Unknown]:  US
    Is <CN=Test User, OU=Support, O=Oracle, L=Reading, ST=Berkshire, C=GB> correct?
      [no]:  yes
    
    Enter key password for <mykey>
            (RETURN if same as keystore password):
    

    Note:

    To determine your 'two-letter country code', use the ISO country code list at the following URL: http://www.bcpl.net/~jspath/isocodes.html.

    The mykeystore file is created in the current directory. The default alias of the key is mykey.

  3. If you do not have a secure-web-site.xml file, then copy the http-web-site.xml to $J2EE_HOME/config/secure-web-site.xml.

  4. Edit secure-web-site.xml with the following elements:

    1. Add secure="true" to the <web-site> element, as follows:

      <web-site port="8888" display-name="Default Oracle Application Server Containers for J2EE Web Site" secure="true">
      
      
    2. Add the following new line inside the <web-site> element to define the keystore and the password.

      <ssl-config keystore="<Your-Keystore>" keystore-password="<Your-Password>" />
      
      

      Where <Your-Keystore> is the full path to the keystore and <Your-Password> is the keystore password. In our example, this is as follows:

      <!-- Enable SSL -->
      <ssl-config keystore="../../keystore" keystore-password="123456"/>
      

      Note:

      The keystore path is relative to where the XML file resides.

    3. Change the web-site port number, to use an available port. For example, the default for SSL ports is 443, so change the Web site port attribute to port="4443". To use the default of 443, you have to be a super user.

    4. Now save the changes to secure-web-site.xml.

  5. If you did not have the secure-web-site.xml file, then edit server.xml to point to the secure-web-site.xml file.

    1. Uncomment or add the following line in the file server.xml so that the secure-web-site.xml file is read.

      <web-site path="./secure-web-site.xml" />
      

      Note:

      Even on Windows, you use a forward slash and not a back slash in the XML files.

    2. Save the changes to server.xml.

  6. Stop and re-start OC4J to initialize the secure-web-site.xml file additions. Test the SSL port by accessing the site in a browser on the SSL port. If successful, you will be asked to accept the certificate, since it is not signed by an accepted authority.

When completed, OC4J listens for SSL requests on one port and non-SSL requests on another. You can disable either SSL requests or non-SSL requests, by commenting out the appropriate *web-site.xml in the server.xml configuration file.

<web-site path="./secure-web-site.xml" /> - comment out this to remove SSL
<default-site path="./http-web-site.xml" /> - comment out this to 
                                                         remove non-SSL

3.5.2.1 Requesting Client Authentication with OC4J Standalone

OC4J supports a "client-authentication" mode in which the server explicitly requests authentication from the client before the server will communicate with the client. In this case, the client must have its own certificate. The client authenticates itself by sending a certificate and a certificate chain that ends with a root certificate. OC4J can be configured to accept only root certificates from a specified list in establishing a chain of trust back to the client.

A certificate that OC4J trusts is called a trust point. This is the first certificate that OC4J encounters in the chain from the client that matches one in its own keystore. There are three ways to configure trust:

  • The client certificate is in the keystore.

  • One of the intermediate certificate authority certificates in the client's chain is in the keystore.

  • The root certificate authority certificate in the client's chain is in the keystore.

OC4J verifies that the entire certificate chain up to and including the trust point is valid to prevent any forged certificates.

If you request client authentication with the needs-client-auth attribute, perform the following:

  1. Decide which of the certificates in the client's chain is to be your trust point. Ensure that you either have control of the issue of certificates using this trust point or that you trust the certificate authority as an issuer.

  2. Import the intermediate or root certificate in the server keystore as a trust point for authentication of the client certificate.

  3. If you do not want OC4J to have access to certain trust points, make sure that these trust points are not in the keystore.

  4. Execute the preceding steps to create the client certificate, which includes the intermediate or root certificate installed in the server. If you wish to trust another certificate authority, obtain a certificate from that authority.

  5. Save the certificate in a file on the client.

  6. Provide the certificate on the client initiation of the HTTPS connection.

    1. If the client is a browser, set the certificate in the client browser security area.

    2. If the client is a Java client, you must programmatically present the client certificate and the certificate chain when initiating the HTTPS connection.

3.5.3 HTTPS Common Problems and Solutions

The following errors may occur when using SSL certificates:

Keytool Error: java.security.cert.CertificateException: Unsupported encoding
Cause: You cannot allow trailing whitespace in the keytool.
Action: Delete all trailing whitespace. If the error still occurs, add a new line in your certificate reply file.
Keytool Error: KeyPairGenerator not available
Cause: You are probably using a keytool from an older JDK.
Action: Use the keytool from the latest JDK on your system. To ensure that you are using the latest JDK, specify the full path for this JDK.
Keytool Error: Failed to establish chain from reply
Cause: The keytool cannot locate the root CA certificates in your keystore; thus, the keytool cannot build the certificate chain from your server key to the trusted root certificate authority.
Action: Execute the following:
keytool -keystore keystore -import -alias cacert -file cacert.cer (keytool -keystore keystore -import -alias intercert -file inter.cer) 

If you use an intermediate CA keytool, then execute the following:

keystore keystore -genkey -keyalg RSA -alias serverkey keytool -keystore keystore -certreq -file my.host.com.csr 

Get the certificate from the Certificate Signing Request, then execute the following:

keytool -keystore keystore -import -file my.host.com.cer -alias serverkey

IllegalArgumentException: Mixing secure and non-secure sites on the same ip + port
Cause: You cannot configure SSL and non-SSL web-sites to listen on the same port and IP address.
Action: Check to see that different ports are assigned within secure-web-site.xml and http-web-site.xml files.

Keytool does not work on HP-UX
Cause: On HP-UX, it has been reported that the 'keytool' does not work with the RSA option.
Action: Generate the key on another platform and FTP it to the HP-UX server.

3.5.3.1 General SSL Debugging

You can get more debug information from the JSSE implementation. To get a list of options, start OC4J with:

java -Djavax.net.debug=help -jar oc4j.jar 

Or, if you want to turn on full verbosity, use:

java -Djavax.net.debug=all -jar oc4j.jar

Both options will display:

  • Browser request header

  • Server HTTP header

  • Server HTTP body (HTML served)

  • Content length (before and after encryption)

  • SSL version

For UNIX, you could use the startup scripts in NOTE 150215.1 'Scripts to Administer OC4J on Unix Platforms', and amend these.